- * // Static import all reflection methods to decrease verbosity
- * import static org.joor.Reflect.*;
- *
- * // Wrap an Object / Class / class name with the on() method:
- * on("java.lang.String")
- * // Invoke constructors using the create() method:
- * .create("Hello World")
- * // Invoke methods using the call() method:
- * .call("toString")
- * // Retrieve the wrapped object
- *
- * @author Lukas Eder
- * @author Irek Matysiewicz
- */
-public class Reflect {
-
- // ---------------------------------------------------------------------
- // Static API used as entrance points to the fluent API
- // ---------------------------------------------------------------------
-
- /**
- * Wrap a class name.
- *
- * This is the same as calling on(Class.forName(name))
- *
- * @param name A fully qualified class name
- * @return A wrapped class object, to be used for further reflection.
- * @throws ReflectException If any reflection exception occurred.
- * @see #on(Class)
- */
- public static Reflect on(String name) throws ReflectException {
- return on(forName(name));
- }
-
- /**
- * Wrap a class name, loading it via a given class loader.
- *
- * This is the same as calling
- * on(Class.forName(name, classLoader))
- *
- * @param name A fully qualified class name.
- * @param classLoader The class loader in whose context the class should be
- * loaded.
- * @return A wrapped class object, to be used for further reflection.
- * @throws ReflectException If any reflection exception occurred.
- * @see #on(Class)
- */
- public static Reflect on(String name, ClassLoader classLoader) throws ReflectException {
- return on(forName(name, classLoader));
- }
-
- /**
- * Wrap a class.
- *
- * Use this when you want to access static fields and methods on a
- * {@link Class} object, or as a basis for constructing objects of that
- * class using {@link #create(Object...)}
- *
- * @param clazz The class to be wrapped
- * @return A wrapped class object, to be used for further reflection.
- */
- public static Reflect on(Class> clazz) {
- return new Reflect(clazz);
- }
-
- /**
- * Wrap an object.
- *
- * Use this when you want to access instance fields and methods on any
- * {@link Object}
- *
- * @param object The object to be wrapped
- * @return A wrapped object, to be used for further reflection.
- */
- public static Reflect on(Object object) {
- return new Reflect(object);
- }
-
- /**
- * Conveniently render an {@link AccessibleObject} accessible.
- *
- * To prevent {@link SecurityException}, this is only done if the argument
- * object and its declaring class are non-public.
- *
- * @param accessible The object to render accessible
- * @return The argument object rendered accessible
- */
- public static T accessible(T accessible) {
- if (accessible == null) {
- return null;
- }
-
- if (accessible instanceof Member) {
- Member member = (Member) accessible;
-
- if (Modifier.isPublic(member.getModifiers()) &&
- Modifier.isPublic(member.getDeclaringClass().getModifiers())) {
-
- return accessible;
- }
- }
-
- // [jOOQ #3392] The accessible flag is set to false by default, also for public members.
- if (!accessible.isAccessible()) {
- accessible.setAccessible(true);
- }
-
- return accessible;
- }
-
- // ---------------------------------------------------------------------
- // Members
- // ---------------------------------------------------------------------
-
- /**
- * The wrapped object
- */
- private final Object object;
-
- /**
- * A flag indicating whether the wrapped object is a {@link Class} (for
- * accessing static fields and methods), or any other type of {@link Object}
- * (for accessing instance fields and methods).
- */
- private final boolean isClass;
-
- // ---------------------------------------------------------------------
- // Constructors
- // ---------------------------------------------------------------------
-
- private Reflect(Class> type) {
- this.object = type;
- this.isClass = true;
- }
-
- private Reflect(Object object) {
- this.object = object;
- this.isClass = false;
- }
-
- // ---------------------------------------------------------------------
- // Fluent Reflection API
- // ---------------------------------------------------------------------
-
- /**
- * Get the wrapped object
- *
- * @param A convenience generic parameter for automatic unsafe casting
- */
- @SuppressWarnings("unchecked")
- public T get() {
- return (T) object;
- }
-
- /**
- * Set a field value.
- *
- * This is roughly equivalent to {@link Field#set(Object, Object)}. If the
- * wrapped object is a {@link Class}, then this will set a value to a static
- * member field. If the wrapped object is any other {@link Object}, then
- * this will set a value to an instance member field.
- *
- * @param name The field name
- * @param value The new field value
- * @return The same wrapped object, to be used for further reflection.
- * @throws ReflectException If any reflection exception occurred.
- */
- public Reflect set(String name, Object value) throws ReflectException {
- try {
- Field field = field0(name);
- field.set(object, unwrap(value));
- return this;
- }
- catch(Exception e) {
- throw new ReflectException(e);
- }
- }
-
- /**
- * Get a field value.
- *
- * This is roughly equivalent to {@link Field#get(Object)}. If the wrapped
- * object is a {@link Class}, then this will get a value from a static
- * member field. If the wrapped object is any other {@link Object}, then
- * this will get a value from an instance member field.
- *
- * If you want to "navigate" to a wrapped version of the field, use
- * {@link #field(String)} instead.
- *
- * @param name The field name
- * @return The field value
- * @throws ReflectException If any reflection exception occurred.
- * @see #field(String)
- */
- public T get(String name) throws ReflectException {
- return field(name).get();
- }
-
- /**
- * Get a wrapped field.
- *
- * This is roughly equivalent to {@link Field#get(Object)}. If the wrapped
- * object is a {@link Class}, then this will wrap a static member field. If
- * the wrapped object is any other {@link Object}, then this wrap an
- * instance member field.
- *
- * @param name The field name
- * @return The wrapped field
- * @throws ReflectException If any reflection exception occurred.
- */
- public Reflect field(String name) throws ReflectException {
- try {
- Field field = field0(name);
- return on(field.get(object));
- }
- catch(Exception e) {
- throw new ReflectException(e);
- }
- }
-
- private Field field0(String name) throws ReflectException {
- Class> type = type();
-
- // Try getting a public field
- try {
- return type.getField(name);
- }
-
- // Try again, getting a non-public field
- catch(NoSuchFieldException e) {
- do {
- try {
- return accessible(type.getDeclaredField(name));
- }
- catch(NoSuchFieldException ignore) {}
-
- type = type.getSuperclass();
- }
- while(type != null);
-
- throw new ReflectException(e);
- }
- }
-
- /**
- * Get a Map containing field names and wrapped values for the fields'
- * values.
- *
- * If the wrapped object is a {@link Class}, then this will return static
- * fields. If the wrapped object is any other {@link Object}, then this will
- * return instance fields.
- *
- * These two calls are equivalent
- * on(object).field("myField");
- * on(object).fields().get("myField");
- *
- *
- * @return A map containing field names and wrapped values.
- */
- public Map fields() {
- Map result = new LinkedHashMap();
- Class> type = type();
-
- do {
- for(Field field : type.getDeclaredFields()) {
- if (!isClass ^ Modifier.isStatic(field.getModifiers())) {
- String name = field.getName();
-
- if (!result.containsKey(name)) { result.put(name, field(name)); }
- }
- }
-
- type = type.getSuperclass();
- }
- while(type != null);
-
- return result;
- }
-
- /**
- * Call a method by its name.
- *
- * This is a convenience method for calling
- * call(name, new Object[0])
- *
- * @param name The method name
- * @return The wrapped method result or the same wrapped object if the
- * method returns void, to be used for further
- * reflection.
- * @throws ReflectException If any reflection exception occurred.
- * @see #call(String, Object...)
- */
- public Reflect call(String name) throws ReflectException {
- return call(name, new Object[0]);
- }
-
- /**
- * Call a method by its name.
- *
- * This is roughly equivalent to {@link Method#invoke(Object, Object...)}.
- * If the wrapped object is a {@link Class}, then this will invoke a static
- * method. If the wrapped object is any other {@link Object}, then this will
- * invoke an instance method.
- *
- * Just like {@link Method#invoke(Object, Object...)}, this will try to wrap
- * primitive types or unwrap primitive type wrappers if applicable. If
- * several methods are applicable, by that rule, the first one encountered
- * is called. i.e. when calling
- * on(...).call("method", 1, 1);
- * The first of the following methods will be called:
- *
- * public void method(int param1, Integer param2);
- * public void method(Integer param1, int param2);
- * public void method(Number param1, Number param2);
- * public void method(Number param1, Object param2);
- * public void method(int param1, Object param2);
- *
- *
- * The best matching method is searched for with the following strategy:
- *
- * - public method with exact signature match in class hierarchy
- * - non-public method with exact signature match on declaring class
- * - public method with similar signature in class hierarchy
- * - non-public method with similar signature on declaring class
- *
- *
- * @param name The method name
- * @param args The method arguments
- * @return The wrapped method result or the same wrapped object if the
- * method returns void, to be used for further
- * reflection.
- * @throws ReflectException If any reflection exception occurred.
- */
- public Reflect call(String name, Object... args) throws ReflectException {
- Class>[] types = types(args);
-
- // Try invoking the "canonical" method, i.e. the one with exact
- // matching argument types
- try {
- Method method = exactMethod(name, types);
- return on(method, object, args);
- }
-
- // If there is no exact match, try to find a method that has a "similar"
- // signature if primitive argument types are converted to their wrappers
- catch (NoSuchMethodException e) {
- try {
- Method method = similarMethod(name, types);
- return on(method, object, args);
- } catch (NoSuchMethodException e1) {
- throw new ReflectException(e1);
- }
- }
- }
-
- /**
- * Searches a method with the exact same signature as desired.
- *
- * If a public method is found in the class hierarchy, this method is returned.
- * Otherwise a private method with the exact same signature is returned.
- * If no exact match could be found, we let the {@code NoSuchMethodException} pass through.
- */
- private Method exactMethod(String name, Class>[] types) throws NoSuchMethodException {
- Class> type = type();
-
- // first priority: find a public method with exact signature match in class hierarchy
- try {
- return type.getMethod(name, types);
- }
-
- // second priority: find a private method with exact signature match on declaring class
- catch (NoSuchMethodException e) {
- do {
- try {
- return type.getDeclaredMethod(name, types);
- }
- catch(NoSuchMethodException ignore) {}
-
- type = type.getSuperclass();
- }
- while(type != null);
-
- throw new NoSuchMethodException();
- }
- }
-
- /**
- * Searches a method with a similar signature as desired using
- * {@link #isSimilarSignature(java.lang.reflect.Method, String, Class[])}.
- *
- * First public methods are searched in the class hierarchy, then private
- * methods on the declaring class. If a method could be found, it is
- * returned, otherwise a {@code NoSuchMethodException} is thrown.
- */
- private Method similarMethod(String name, Class>[] types) throws NoSuchMethodException {
- Class> type = type();
-
- // first priority: find a public method with a "similar" signature in class hierarchy
- // similar interpreted in when primitive argument types are converted to their wrappers
- for (Method method : type.getMethods()) {
- if (isSimilarSignature(method, name, types)) {
- return method;
- }
- }
-
- // second priority: find a non-public method with a "similar" signature on declaring class
- do {
- for(Method method : type.getDeclaredMethods()) {
- if (isSimilarSignature(method, name, types)) {
- return method;
- }
- }
-
- type = type.getSuperclass();
- }
- while(type != null);
-
- throw new NoSuchMethodException("No similar method " + name + " with params " + Arrays.toString(types) + " could be found on type " + type() + ".");
- }
-
- /**
- * Determines if a method has a "similar" signature, especially if wrapping
- * primitive argument types would result in an exactly matching signature.
- */
- private boolean isSimilarSignature(Method possiblyMatchingMethod, String desiredMethodName, Class>[] desiredParamTypes) {
- return possiblyMatchingMethod.getName().equals(desiredMethodName) && match(possiblyMatchingMethod.getParameterTypes(), desiredParamTypes);
- }
-
- /**
- * Call a constructor.
- *
- * This is a convenience method for calling
- * create(new Object[0])
- *
- * @return The wrapped new object, to be used for further reflection.
- * @throws ReflectException If any reflection exception occurred.
- * @see #create(Object...)
- */
- public Reflect create() throws ReflectException {
- return create(new Object[0]);
- }
-
- /**
- * Call a constructor.
- *
- * This is roughly equivalent to {@link Constructor#newInstance(Object...)}.
- * If the wrapped object is a {@link Class}, then this will create a new
- * object of that class. If the wrapped object is any other {@link Object},
- * then this will create a new object of the same type.
- *
- * Just like {@link Constructor#newInstance(Object...)}, this will try to
- * wrap primitive types or unwrap primitive type wrappers if applicable. If
- * several constructors are applicable, by that rule, the first one
- * encountered is called. i.e. when calling
- * on(C.class).create(1, 1);
- *
The first of the following constructors will be applied:
- *
- * public C(int param1, Integer param2);
- * public C(Integer param1, int param2);
- * public C(Number param1, Number param2);
- * public C(Number param1, Object param2);
- * public C(int param1, Object param2);
- *
- *
- * @param args The constructor arguments
- * @return The wrapped new object, to be used for further reflection.
- * @throws ReflectException If any reflection exception occurred.
- */
- public Reflect create(Object... args) throws ReflectException {
- Class>[] types = types(args);
-
- // Try invoking the "canonical" constructor, i.e. the one with exact
- // matching argument types
- try {
- Constructor> constructor = type().getDeclaredConstructor(types);
- return on(constructor, args);
- }
-
- // If there is no exact match, try to find one that has a "similar"
- // signature if primitive argument types are converted to their wrappers
- catch (NoSuchMethodException e) {
- for(Constructor> constructor : type().getDeclaredConstructors()) {
- if (match(constructor.getParameterTypes(), types)) {
- return on(constructor, args);
- }
- }
-
- throw new ReflectException(e);
- }
- }
-
- /**
- * Create a proxy for the wrapped object allowing to typesafely invoke
- * methods on it using a custom interface
- *
- * @param proxyType The interface type that is implemented by the proxy
- * @return A proxy for the wrapped object
- */
- @SuppressWarnings("unchecked")
- public
P as(Class
proxyType) {
- final boolean isMap = (object instanceof Map);
- final InvocationHandler handler = new InvocationHandler() {
- @SuppressWarnings("null")
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- String name = method.getName();
-
- // Actual method name matches always come first
- try {
- return on(object).call(name, args).get();
- }
-
- // [#14] Emulate POJO behaviour on wrapped map objects
- catch (ReflectException e) {
- if (isMap) {
- Map map = (Map) object;
- int length = (args == null ? 0 : args.length);
-
- if (length == 0 && name.startsWith("get")) {
- return map.get(property(name.substring(3)));
- }
- else if (length == 0 && name.startsWith("is")) {
- return map.get(property(name.substring(2)));
- }
- else if (length == 1 && name.startsWith("set")) {
- map.put(property(name.substring(3)), args[0]);
- return null;
- }
- }
-
- throw e;
- }
- }
- };
-
- return (P) Proxy.newProxyInstance(proxyType.getClassLoader(), new Class[] { proxyType }, handler);
- }
-
- /**
- * Get the POJO property name of an getter/setter
- */
- private static String property(String string) {
- int length = string.length();
-
- if (length == 0) {
- return "";
- }
- else if (length == 1) {
- return string.toLowerCase(Locale.ENGLISH);
- }
- else {
- return string.substring(0, 1).toLowerCase(Locale.ENGLISH) + string.substring(1);
- }
- }
-
- // ---------------------------------------------------------------------
- // Object API
- // ---------------------------------------------------------------------
-
- /**
- * Check whether two arrays of types match, converting primitive types to
- * their corresponding wrappers.
- */
- private boolean match(Class>[] declaredTypes, Class>[] actualTypes) {
- if (declaredTypes.length == actualTypes.length) {
- for (int i = 0; i < actualTypes.length; i++) {
- if (actualTypes[i] == NULL.class)
- continue;
-
- if (wrapper(declaredTypes[i]).isAssignableFrom(wrapper(actualTypes[i])))
- continue;
-
- return false;
- }
-
- return true;
- }
- else {
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
- return object.hashCode();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Reflect) {
- return object.equals(((Reflect) obj).get());
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return object.toString();
- }
-
- // ---------------------------------------------------------------------
- // Utility methods
- // ---------------------------------------------------------------------
-
- /**
- * Wrap an object created from a constructor
- */
- private static Reflect on(Constructor> constructor, Object... args) throws ReflectException {
- try {
- return on(accessible(constructor).newInstance(args));
- }
- catch (Exception e) {
- throw new ReflectException(e);
- }
- }
-
- /**
- * Wrap an object returned from a method
- */
- private static Reflect on(Method method, Object object, Object... args) throws ReflectException {
- try {
- accessible(method);
-
- if (method.getReturnType() == void.class) {
- method.invoke(object, args);
- return on(object);
- }
- else {
- return on(method.invoke(object, args));
- }
- }
- catch (Exception e) {
- throw new ReflectException(e);
- }
- }
-
- /**
- * Unwrap an object
- */
- private static Object unwrap(Object object) {
- if (object instanceof Reflect) {
- return ((Reflect) object).get();
- }
-
- return object;
- }
-
- /**
- * Get an array of types for an array of objects
- *
- * @see Object#getClass()
- */
- private static Class>[] types(Object... values) {
- if (values == null) {
- return new Class[0];
- }
-
- Class>[] result = new Class[values.length];
-
- for (int i = 0; i < values.length; i++) {
- Object value = values[i];
- result[i] = value == null ? NULL.class : value.getClass();
- }
-
- return result;
- }
-
- /**
- * Load a class
- *
- * @see Class#forName(String)
- */
- private static Class> forName(String name) throws ReflectException {
- try {
- return Class.forName(name);
- }
- catch (Exception e) {
- throw new ReflectException(e);
- }
- }
-
- private static Class> forName(String name, ClassLoader classLoader) throws ReflectException {
- try {
- return Class.forName(name, true, classLoader);
- }
- catch(Exception e) {
- throw new ReflectException(e);
- }
- }
-
- /**
- * Get the type of the wrapped object.
- *
- * @see Object#getClass()
- */
- public Class> type() {
- if (isClass) {
- return (Class>) object;
- }
- else {
- return object.getClass();
- }
- }
-
- /**
- * Get a wrapper type for a primitive type, or the argument type itself, if
- * it is not a primitive type.
- */
- public static Class> wrapper(Class> type) {
- if (type == null) {
- return null;
- }
- else if (type.isPrimitive()) {
- if (boolean.class == type) {
- return Boolean.class;
- }
- else if (int.class == type) {
- return Integer.class;
- }
- else if (long.class == type) {
- return Long.class;
- }
- else if (short.class == type) {
- return Short.class;
- }
- else if (byte.class == type) {
- return Byte.class;
- }
- else if (double.class == type) {
- return Double.class;
- }
- else if (float.class == type) {
- return Float.class;
- }
- else if (char.class == type) {
- return Character.class;
- }
- else if (void.class == type) {
- return Void.class;
- }
- }
-
- return type;
- }
-
- private static class NULL {}
-}
diff --git a/old code/tray/src/org/joor/ReflectException.java b/old code/tray/src/org/joor/ReflectException.java
deleted file mode 100755
index 3598246..0000000
--- a/old code/tray/src/org/joor/ReflectException.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
- * All rights reserved.
- *
- * This software is licensed to you under the Apache License, Version 2.0
- * (the "License"); You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * . Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * . Neither the name "jOOR" nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-package org.joor;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * A unchecked wrapper for any of Java's checked reflection exceptions:
- *
- * These exceptions are
- *
- * - {@link ClassNotFoundException}
- * - {@link IllegalAccessException}
- * - {@link IllegalArgumentException}
- * - {@link InstantiationException}
- * - {@link InvocationTargetException}
- * - {@link NoSuchMethodException}
- * - {@link NoSuchFieldException}
- * - {@link SecurityException}
- *
- *
- * @author Lukas Eder
- */
-public class ReflectException extends RuntimeException {
-
- /**
- * Generated UID
- */
- private static final long serialVersionUID = -6213149635297151442L;
-
- public ReflectException(String message) {
- super(message);
- }
-
- public ReflectException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public ReflectException() {
- super();
- }
-
- public ReflectException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/old code/tray/src/qz/App.java b/old code/tray/src/qz/App.java
deleted file mode 100755
index 7b363b6..0000000
--- a/old code/tray/src/qz/App.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package qz;
-
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Filter;
-import org.apache.logging.log4j.core.appender.RollingFileAppender;
-import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
-import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
-import org.apache.logging.log4j.core.filter.ThresholdFilter;
-import org.apache.logging.log4j.core.layout.PatternLayout;
-import qz.build.provision.params.Phase;
-import qz.common.Constants;
-import qz.installer.Installer;
-import qz.installer.certificate.CertificateManager;
-import qz.installer.certificate.ExpiryTask;
-import qz.installer.certificate.KeyPairWrapper;
-import qz.installer.certificate.NativeCertificateInstaller;
-import qz.installer.provision.ProvisionInstaller;
-import qz.ui.PairingConfigDialog;
-import qz.utils.*;
-import qz.ws.PrintSocketServer;
-import qz.ws.SingleInstanceChecker;
-import qz.ws.substitutions.Substitutions;
-
-import java.io.File;
-import java.security.cert.X509Certificate;
-import java.util.Properties;
-
-public class App {
- private static final Logger log = LogManager.getLogger(App.class);
- private static Properties trayProperties = null;
-
- public static void main(String ... args) {
- ArgParser parser = new ArgParser(args);
- LibUtilities.getInstance().bind();
- if(parser.intercept()) {
- FileUtilities.cleanup();
- System.exit(parser.getExitCode());
- }
- SingleInstanceChecker.stealWebsocket = parser.hasFlag(ArgValue.STEAL);
- setupFileLogging();
- log.info(Constants.ABOUT_TITLE + " version: {}", Constants.VERSION);
- log.info(Constants.ABOUT_TITLE + " vendor: {}", Constants.ABOUT_COMPANY);
- log.info("Java version: {}", Constants.JAVA_VERSION.toString());
- log.info("Java vendor: {}", Constants.JAVA_VENDOR);
- Substitutions.setEnabled(PrefsSearch.getBoolean(ArgValue.SECURITY_SUBSTITUTIONS_ENABLE));
- Substitutions.setStrict(PrefsSearch.getBoolean(ArgValue.SECURITY_SUBSTITUTIONS_STRICT));
-
- CertificateManager certManager = null;
- try {
- // Gets and sets the SSL info, properties file
- certManager = Installer.getInstance().certGen(false);
- trayProperties = certManager.getProperties();
- // Reoccurring (e.g. hourly) cert expiration check
- new ExpiryTask(certManager).schedule();
- } catch(Exception e) {
- log.error("Something went critically wrong loading HTTPS", e);
- }
- Installer.getInstance().addUserSettings();
-
- // Load overridable preferences set in qz-tray.properties file
- NetworkUtilities.setPreferences(certManager.getProperties());
- SingleInstanceChecker.setPreferences(certManager.getProperties());
-
- // Linux needs the cert installed in user-space on every launch for Chrome SSL to work
- if(!SystemUtilities.isWindows() && !SystemUtilities.isMac()) {
- X509Certificate caCert = certManager.getKeyPair(KeyPairWrapper.Type.CA).getCert();
- // Only install if a CA cert exists (e.g. one we generated)
- if(caCert != null) {
- NativeCertificateInstaller.getInstance().install(certManager.getKeyPair(KeyPairWrapper.Type.CA).getCert());
- }
- }
-
- // Invoke any provisioning steps that are phase=startup
- try {
- ProvisionInstaller provisionInstaller = new ProvisionInstaller(SystemUtilities.getJarParentPath().resolve(Constants.PROVISION_DIR));
- provisionInstaller.invoke(Phase.STARTUP);
- } catch(Exception e) {
- log.warn("An error occurred provisioning \"phase\": \"startup\" entries", e);
- }
-
- try {
- log.info("Starting {} {}", Constants.ABOUT_TITLE, Constants.VERSION);
- // Start the WebSocket
- PrintSocketServer.runServer(certManager, parser.isHeadless());
- }
- catch(Exception e) {
- log.error("Could not start tray manager", e);
- }
- FileUtilities.cleanup();
- log.warn("The web socket server is no longer running");
-
- // Show pairing config dialog if needed
- PairingConfigDialog.showIfNeeded(null); // null for no parent frame, or pass your main frame if available
- }
-
- public static Properties getTrayProperties() {
- return trayProperties;
- }
-
- private static void setupFileLogging() {
- //disable jetty logging
- System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog");
- System.setProperty("org.eclipse.jetty.LEVEL", "OFF");
-
- if(PrefsSearch.getBoolean(ArgValue.LOG_DISABLE)) {
- return;
- }
-
- int logSize = PrefsSearch.getInt(ArgValue.LOG_SIZE);
- int logRotate = PrefsSearch.getInt(ArgValue.LOG_ROTATE);
- Installer.getInstance().cleanupLegacyLogs(Math.max(logRotate, 5));
- RollingFileAppender fileAppender = RollingFileAppender.newBuilder()
- .setName("log-file")
- .withAppend(true)
- .setLayout(PatternLayout.newBuilder().withPattern("%d{ISO8601} [%p] %m%n").build())
- .setFilter(ThresholdFilter.createFilter(Level.DEBUG, Filter.Result.ACCEPT, Filter.Result.DENY))
- .withFileName(FileUtilities.USER_DIR + File.separator + Constants.LOG_FILE + ".log")
- .withFilePattern(FileUtilities.USER_DIR + File.separator + Constants.LOG_FILE + ".%i.log")
- .withStrategy(DefaultRolloverStrategy.newBuilder()
- .withMax(String.valueOf(logRotate))
- .withFileIndex("min")
- .build())
- .withPolicy(SizeBasedTriggeringPolicy.createPolicy(String.valueOf(logSize)))
- .withImmediateFlush(true)
- .build();
- fileAppender.start();
-
- LoggerUtilities.getRootLogger().addAppender(fileAppender);
- }
-}
diff --git a/old code/tray/src/qz/auth/CRL.java b/old code/tray/src/qz/auth/CRL.java
deleted file mode 100755
index 861235e..0000000
--- a/old code/tray/src/qz/auth/CRL.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package qz.auth;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import qz.utils.ConnectionUtilities;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-
-/**
- * Wrapper class for the Certificate Revocation List
- * Created by Steven on 2/4/2015. Package: qz.auth Project: qz-print
- */
-public class CRL {
-
- private static final Logger log = LogManager.getLogger(CRL.class);
-
- /** The URL to the QZ CRL. Should not be changed except for dev tests */
- public static final String CRL_URL = "https://crl.qz.io";
-
- private static CRL instance = null;
-
- private ArrayList revokedHashes = new ArrayList();
- private boolean loaded = false;
-
-
- private CRL() {}
-
- public static CRL getInstance() {
- if (instance == null) {
- instance = new CRL();
-
- new Thread() {
- @Override
- public void run() {
- log.info("Loading CRL from {}", CRL_URL);
-
- try(BufferedReader br = new BufferedReader(new InputStreamReader(ConnectionUtilities.getInputStream(CRL_URL, false)))) {
- String line;
- while((line = br.readLine()) != null) {
- //Ignore empty and commented lines
- if (!line.isEmpty() && line.charAt(0) != '#') {
- instance.revokedHashes.add(line);
- }
- }
-
- instance.loaded = true;
- log.info("Successfully loaded {} CRL entries from {}", instance.revokedHashes.size(), CRL_URL);
- }
- catch(IOException e) {
- log.warn("Unable to access CRL from {}, {}", CRL_URL, e.toString());
- }
- }
- }.start();
- }
-
- return instance;
- }
-
- public boolean isRevoked(String fingerprint) {
- return revokedHashes.contains(fingerprint);
- }
-
- public boolean isLoaded() {
- return loaded;
- }
-}
diff --git a/old code/tray/src/qz/auth/Certificate.java b/old code/tray/src/qz/auth/Certificate.java
deleted file mode 100755
index be58e9b..0000000
--- a/old code/tray/src/qz/auth/Certificate.java
+++ /dev/null
@@ -1,536 +0,0 @@
-package qz.auth;
-
-import org.apache.commons.codec.binary.StringUtils;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.Charsets;
-import org.apache.commons.ssl.Base64;
-import org.apache.commons.ssl.X509CertificateChainBuilder;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.x500.style.BCStyle;
-import org.bouncycastle.jce.PrincipalUtil;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import qz.App;
-import qz.common.Constants;
-import qz.utils.*;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.*;
-import java.security.cert.*;
-import java.time.DateTimeException;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.time.format.DateTimeFormatter;
-import java.util.*;
-
-/**
- * Created by Steven on 1/27/2015. Package: qz.auth Project: qz-print
- * Wrapper to store certificate objects from
- */
-public class Certificate {
-
- private static final Logger log = LogManager.getLogger(Certificate.class);
- private static final String QUIETLY_FAIL = "quiet";
-
- public enum Algorithm {
- SHA1("SHA1withRSA"),
- SHA256("SHA256withRSA"),
- SHA512("SHA512withRSA");
-
- String name;
-
- Algorithm(String name) {
- this.name = name;
- }
- }
-
- public static ArrayList rootCAs = new ArrayList<>();
- public static Certificate builtIn;
- private static CertPathValidator validator;
- private static CertificateFactory factory;
- private static boolean trustBuiltIn = false;
- // id-at-description used for storing renewal information
- private static ASN1ObjectIdentifier RENEWAL_OF = new ASN1ObjectIdentifier("2.5.4.13");
-
- public static final String[] saveFields = new String[] {"fingerprint", "commonName", "organization", "validFrom", "validTo", "valid"};
-
- public static final String SPONSORED_CN_PREFIX = "Sponsored:";
-
- // Valid date range allows UI to only show "Expired" text for valid certificates
- private static final Instant UNKNOWN_MIN = LocalDateTime.MIN.toInstant(ZoneOffset.UTC);
- private static final Instant UNKNOWN_MAX = LocalDateTime.MAX.toInstant(ZoneOffset.UTC);
- public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- public static final DateTimeFormatter DATE_PARSE = DateTimeFormatter.ofPattern("uuuu-MM-dd['T'][ ]HH:mm:ss[.n]['Z']"); //allow parsing of both ISO and custom formatted dates
-
- private X509Certificate theCertificate;
- private boolean sponsored;
- private String fingerprint;
- private String commonName;
- private String organization;
- private Instant validFrom;
- private Instant validTo;
-
- //used by review sites UI only
- private boolean expired = false;
- private boolean valid = false;
- private boolean rootCA = false; // TODO: Move to constructor?
-
-
- //Pre-set certificate for use when missing
- public static final Certificate UNKNOWN;
-
- static {
- HashMap map = new HashMap<>();
- map.put("fingerprint", "UNKNOWN REQUEST");
- map.put("commonName", "An anonymous request");
- map.put("organization", "Unknown");
- map.put("validFrom", UNKNOWN_MIN.toString());
- map.put("validTo", UNKNOWN_MAX.toString());
- map.put("valid", "false");
- UNKNOWN = Certificate.loadCertificate(map);
- }
-
- static {
- try {
- Security.addProvider(new BouncyCastleProvider());
- validator = CertPathValidator.getInstance("PKIX");
- factory = CertificateFactory.getInstance("X.509");
- builtIn = new Certificate("-----BEGIN CERTIFICATE-----\n" +
- "MIIELzCCAxegAwIBAgIJALm151zCHDxiMA0GCSqGSIb3DQEBCwUAMIGsMQswCQYD\n" +
- "VQQGEwJVUzELMAkGA1UECAwCTlkxEjAQBgNVBAcMCUNhbmFzdG90YTEbMBkGA1UE\n" +
- "CgwSUVogSW5kdXN0cmllcywgTExDMRswGQYDVQQLDBJRWiBJbmR1c3RyaWVzLCBM\n" +
- "TEMxGTAXBgNVBAMMEHF6aW5kdXN0cmllcy5jb20xJzAlBgkqhkiG9w0BCQEWGHN1\n" +
- "cHBvcnRAcXppbmR1c3RyaWVzLmNvbTAgFw0xNTAzMDEyMzM4MjlaGA8yMTE1MDMw\n" +
- "MjIzMzgyOVowgawxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTESMBAGA1UEBwwJ\n" +
- "Q2FuYXN0b3RhMRswGQYDVQQKDBJRWiBJbmR1c3RyaWVzLCBMTEMxGzAZBgNVBAsM\n" +
- "ElFaIEluZHVzdHJpZXMsIExMQzEZMBcGA1UEAwwQcXppbmR1c3RyaWVzLmNvbTEn\n" +
- "MCUGCSqGSIb3DQEJARYYc3VwcG9ydEBxemluZHVzdHJpZXMuY29tMIIBIjANBgkq\n" +
- "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuWsBa6uk+RM4OKBZTRfIIyqaaFD71FAS\n" +
- "7kojAQ+ySMpYuqLjIVZuCh92o1FGBvyBKUFc6knAHw5749yhLCYLXhzWwiNW2ri1\n" +
- "Jwx/d83Wnaw6qA3lt++u3tmiA8tsFtss0QZW0YBpFsIqhamvB3ypwu0bdUV/oH7g\n" +
- "/s8TFR5LrDfnfxlLFYhTUVWuWzMqEFAGnFG3uw/QMWZnQgkGbx0LMcYzdqFb7/vz\n" +
- "rTSHfjJsisUTWPjo7SBnAtNYCYaGj0YH5RFUdabnvoTdV2XpA5IPYa9Q597g/M0z\n" +
- "icAjuaK614nKXDaAUCbjki8RL3OK9KY920zNFboq/jKG6rKW2t51ZQIDAQABo1Aw\n" +
- "TjAdBgNVHQ4EFgQUA0XGTcD6jqkL2oMPQaVtEgZDqV4wHwYDVR0jBBgwFoAUA0XG\n" +
- "TcD6jqkL2oMPQaVtEgZDqV4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n" +
- "AQEAijcT5QMVqrWWqpNEe1DidzQfSnKo17ZogHW+BfUbxv65JbDIntnk1XgtLTKB\n" +
- "VAdIWUtGZbXxrp16NEsh96V2hjDIoiAaEpW+Cp6AHhIVgVh7Q9Knq9xZ1t6H8PL5\n" +
- "QiYQKQgJ0HapdCxlPKBfUm/Mj1ppNl9mPFJwgHmzORexbxrzU/M5i2jlies+CXNq\n" +
- "cvmF2l33QNHnLwpFGwYKs08pyHwUPp6+bfci6lRvavztgvnKroWWIRq9ZPlC0yVK\n" +
- "FFemhbCd7ZVbrTo0NcWZM1PTAbvlOikV9eh3i1Vot+3dJ8F27KwUTtnV0B9Jrxum\n" +
- "W9P3C48mvwTxYZJFOu0N9UBLLg==\n" +
- "-----END CERTIFICATE-----");
-
- builtIn.valid = true;
- setTrustBuiltIn(true);
- scanAdditionalCAs();
- }
- catch(NoSuchAlgorithmException | CertificateException e) {
- e.printStackTrace();
- }
- }
-
- public static void scanAdditionalCAs() {
- ArrayList> certPaths = new ArrayList<>();
- // First, look for "authcert.override", "-DtrustedRootCert"
- certPaths.addAll(FileUtilities.parseDelimitedPaths(PrefsSearch.getString(ArgValue.AUTHCERT_OVERRIDE, App.getTrayProperties())));
-
- // Second, look for "override.crt" within App directory
- certPaths.add(new AbstractMap.SimpleEntry<>(SystemUtilities.getJarParentPath().resolve(Constants.OVERRIDE_CERT), QUIETLY_FAIL));
-
- for(Map.Entry certPath : certPaths) {
- if(certPath.getKey() != null) {
- if (certPath.getKey().toFile().exists()) {
- try {
- Certificate caCert = new Certificate(FileUtilities.readLocalFile(certPath.getKey()));
- caCert.rootCA = true;
- caCert.valid = true;
- if(!rootCAs.contains(caCert)) {
- log.debug("Adding CA certificate: CN={}, O={} ({})",
- caCert.getCommonName(), caCert.getOrganization(), caCert.getFingerprint());
- rootCAs.add(caCert);
- } else {
- log.warn("CA cert exists, skipping: {}", certPath.getKey());
- }
- }
- catch(Exception e) {
- log.error("Error loading CA cert: {}", certPath.getKey(), e);
- }
- } else if(!certPath.getValue().equals(QUIETLY_FAIL)) {
- log.warn("CA cert \"{}\" was provided, but could not be found, skipping.", certPath.getKey());
- }
- }
- }
- }
-
- public Certificate(Path path) throws IOException, CertificateException {
- this(new String(Files.readAllBytes(path), Charsets.UTF_8));
- }
-
- /** Decodes a certificate and intermediate certificate from the given string */
- public Certificate(String in) throws CertificateException {
- try {
- //Strip beginning and end
- String[] split = in.split("--START INTERMEDIATE CERT--");
- byte[] serverCertificate = Base64.decodeBase64(split[0].replaceAll(X509Constants.BEGIN_CERT, "").replaceAll(X509Constants.END_CERT, ""));
-
- X509Certificate theIntermediateCertificate;
- if (split.length == 2) {
- byte[] intermediateCertificate = Base64.decodeBase64(split[1].replaceAll(X509Constants.BEGIN_CERT, "").replaceAll(X509Constants.END_CERT, ""));
- theIntermediateCertificate = (X509Certificate)factory.generateCertificate(new ByteArrayInputStream(intermediateCertificate));
- } else {
- theIntermediateCertificate = null; //Self-signed
- }
-
- //Generate cert
- theCertificate = (X509Certificate)factory.generateCertificate(new ByteArrayInputStream(serverCertificate));
- commonName = getSubjectX509Principal(theCertificate, BCStyle.CN);
- if(commonName.isEmpty()) {
- throw new CertificateException("Common Name cannot be blank.");
- }
- // Remove "Sponsored: " from CN, we'll swap the trusted icon instead <3
- if(commonName.startsWith(SPONSORED_CN_PREFIX)) {
- commonName = commonName.split(SPONSORED_CN_PREFIX)[1].trim();
- sponsored = true;
- } else {
- sponsored = false;
- }
- fingerprint = makeThumbPrint(theCertificate);
- organization = getSubjectX509Principal(theCertificate, BCStyle.O);
- validFrom = theCertificate.getNotBefore().toInstant();
- validTo = theCertificate.getNotAfter().toInstant();
-
- // Check trust anchor against all root certs
- Certificate foundRoot = null;
- if(!this.rootCA) {
- for(Certificate rootCA : rootCAs) {
- HashSet chain = new HashSet<>();
- try {
- chain.add(rootCA.theCertificate);
- if (theIntermediateCertificate != null) { chain.add(theIntermediateCertificate); }
- X509Certificate[] x509Certificates = X509CertificateChainBuilder.buildPath(theCertificate, chain);
-
- Set anchor = new HashSet<>();
- anchor.add(new TrustAnchor(rootCA.theCertificate, null));
- PKIXParameters params = new PKIXParameters(anchor);
- params.setRevocationEnabled(false); // TODO: Re-enable, remove proprietary CRL
- validator.validate(factory.generateCertPath(Arrays.asList(x509Certificates)), params);
- foundRoot = rootCA;
- valid = true;
- log.debug("Successfully chained certificate: CN={}, O={} ({})", getCommonName(), getOrganization(), getFingerprint());
- break; // if successful, don't attempt another chain
- }
- catch(Exception e) {
- log.warn("Problem building certificate chain (normal if multiple CAs are in use)");
- }
- }
- }
-
- // Check for expiration
- Instant now = Instant.now();
- if (expired = (validFrom.isAfter(now) || validTo.isBefore(now))) {
- log.warn("Certificate is expired: CN={}, O={} ({})", getCommonName(), getOrganization(), getFingerprint());
- valid = false;
- }
-
- // If cert matches a rootCA trust it blindly
- // If cert is chained to a 3rd party rootCA, trust it blindly as well
- Iterator allCerts = rootCAs.iterator();
- while(allCerts.hasNext()) {
- Certificate cert = allCerts.next();
- if(cert.equals(this) || (cert.equals(foundRoot) && !cert.equals(builtIn))) {
- log.debug("Adding {} to {} list", cert.toString(), Constants.ALLOW_FILE);
- if(!isSaved()) {
- FileUtilities.printLineToFile(Constants.ALLOW_FILE, data());
- }
- valid = true;
- break;
- }
- }
-
- readRenewalInfo();
- CRL qzCrl = CRL.getInstance();
- if (qzCrl.isLoaded()) {
- if (qzCrl.isRevoked(getFingerprint()) || (theIntermediateCertificate != null && qzCrl.isRevoked(makeThumbPrint(theIntermediateCertificate)))) {
- log.error("Certificate has been revoked and can no longer be used: CN={}, O={} ({})", getCommonName(), getOrganization(), getFingerprint());
- valid = false;
- }
- } else {
- //Assume nothing is revoked, because we can't get the CRL
- log.warn("Failed to retrieve QZ CRL, skipping CRL check");
- }
- }
- catch(Exception e) {
- CertificateException certificateException = new CertificateException();
- certificateException.initCause(e);
- throw certificateException;
- }
- }
-
- private void readRenewalInfo() throws Exception {
- Vector values = PrincipalUtil.getSubjectX509Principal(theCertificate).getValues(RENEWAL_OF);
- Iterator renewals = values.iterator();
-
- while(renewals.hasNext()) {
- String renewalInfo = String.valueOf(renewals.next());
-
- String renewalPrefix = "renewal-of-";
- if (!renewalInfo.startsWith(renewalPrefix)) {
- log.warn("Malformed renewal info: {}", renewalInfo);
- continue;
- }
- String previousFingerprint = renewalInfo.substring(renewalPrefix.length());
- if (previousFingerprint.length() != 40) {
- log.warn("Malformed renewal fingerprint: {}", previousFingerprint);
- continue;
- }
-
- // Add this certificate to the whitelist if the previous certificate was whitelisted
-
- // First, handle shared directory
- File sharedFile = FileUtilities.getFile(Constants.ALLOW_FILE, false);
- if (existsInAnyFile(previousFingerprint, sharedFile) && !isSaved(false)) {
- if(!FileUtilities.printLineToFile(Constants.ALLOW_FILE, data(), false)) {
- // Fallback to local directory if shared is not writable
- FileUtilities.printLineToFile(Constants.ALLOW_FILE, data(), /* fallback */ true);
- }
- }
-
- // Second, handle local directory
- File localFile = FileUtilities.getFile(Constants.ALLOW_FILE, true);
- if (existsInAnyFile(previousFingerprint, localFile) && !isSaved(true)) {
- FileUtilities.printLineToFile(Constants.ALLOW_FILE, data(), true);
- }
- }
- }
-
- private Certificate() {}
-
-
- /**
- * Used to rebuild a certificate for the 'Saved Sites' screen without having to decrypt the certificates again
- */
- public static Certificate loadCertificate(HashMap data) {
- Certificate cert = new Certificate();
-
- cert.fingerprint = data.get("fingerprint");
- cert.commonName = data.get("commonName");
- cert.organization = data.get("organization");
-
- try {
- cert.validFrom = Instant.from(LocalDateTime.from(DATE_PARSE.parse(data.get("validFrom"))).atZone(ZoneOffset.UTC));
- cert.validTo = Instant.from(LocalDateTime.from(DATE_PARSE.parse(data.get("validTo"))).atZone(ZoneOffset.UTC));
- }
- catch(DateTimeException e) {
- cert.validFrom = UNKNOWN_MIN;
- cert.validTo = UNKNOWN_MAX;
-
- log.warn("Unable to parse certificate date: {}", e.getMessage());
- }
-
- cert.valid = Boolean.parseBoolean(data.get("valid"));
-
- return cert;
- }
-
- /**
- * Checks given signature for given data against this certificate,
- * ensuring it is properly signed
- *
- * @param signature the signature appended to the data, base64 encoded
- * @param data the data to check
- * @return true if signature valid, false if not
- */
- public boolean isSignatureValid(Algorithm algorithm, String signature, String data) {
- if (!signature.isEmpty()) {
- //On errors, assume failure.
- try {
- Signature verifier = Signature.getInstance(algorithm.name);
- verifier.initVerify(theCertificate.getPublicKey());
- verifier.update(StringUtils.getBytesUtf8(DigestUtils.sha256Hex(data)));
-
- return verifier.verify(Base64.decodeBase64(signature));
- }
- catch(GeneralSecurityException e) {
- log.error("Unable to verify signature", e);
- }
- }
-
- return false;
- }
-
- /** Checks if the certificate has been added to the specified allow file */
- public boolean isSaved(boolean local) {
- File allowed = FileUtilities.getFile(Constants.ALLOW_FILE, local);
- return existsInAnyFile(getFingerprint(), allowed);
- }
-
- /** Checks if the certificate has been added to any allow file */
- public boolean isSaved() {
- return isSaved(false) || isSaved(true);
- }
-
- /** Checks if the certificate has been added to the local block file */
- public boolean isBlocked() {
- File blocks = FileUtilities.getFile(Constants.BLOCK_FILE, true);
- File blocksShared = FileUtilities.getFile(Constants.BLOCK_FILE, false);
- return existsInAnyFile(getFingerprint(), blocksShared, blocks);
- }
-
- private static boolean existsInAnyFile(String fingerprint, File... files) {
- for(File file : files) {
- if (file == null) { continue; }
-
- try(BufferedReader br = new BufferedReader(new FileReader(file))) {
- String line;
- while((line = br.readLine()) != null) {
- if (line.contains("\t")) {
- String print = line.substring(0, line.indexOf("\t"));
- if (print.equals(fingerprint)) {
- return true;
- }
- }
- }
- }
- catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- return false;
- }
-
-
- public String getFingerprint() {
- return fingerprint;
- }
-
- public String getCommonName() {
- return commonName;
- }
-
- public String getOrganization() {
- return organization;
- }
-
- public String getValidFrom() {
- if (validFrom.isAfter(UNKNOWN_MIN)) {
- return DATE_FORMAT.format(validFrom.atZone(ZoneOffset.UTC));
- } else {
- return "Not Provided";
- }
- }
-
- public String getValidTo() {
- if (validTo.isBefore(UNKNOWN_MAX)) {
- return DATE_FORMAT.format(validTo.atZone(ZoneOffset.UTC));
- } else {
- return "Not Provided";
- }
- }
-
- public Instant getValidFromDate() {
- return validFrom;
- }
-
- public Instant getValidToDate() {
- return validTo;
- }
-
- /**
- * Validates certificate against embedded cert.
- */
- public boolean isTrusted() {
- return isValid() && !isExpired();
- }
-
- public boolean isSponsored() {
- return sponsored;
- }
-
- public boolean isValid() {
- return valid;
- }
-
- public boolean isExpired() {
- return expired;
- }
-
-
- public static String makeThumbPrint(X509Certificate cert) throws NoSuchAlgorithmException, CertificateEncodingException {
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- md.update(cert.getEncoded());
- return ByteUtilities.bytesToHex(md.digest(), false);
- }
-
- private String data(boolean assumeTrusted) {
- return getFingerprint() + "\t" +
- getCommonName() + "\t" +
- getOrganization() + "\t" +
- getValidFrom() + "\t" +
- getValidTo() + "\t" +
- // Used by equals(), may fail if it hasn't been trusted yet
- (assumeTrusted ? true : isTrusted());
- }
-
- public String data() {
- return data(false);
- }
-
- @Override
- public String toString() {
- return getOrganization() + " (" + getCommonName() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Certificate) {
- return ((Certificate)obj).data(true).equals(data(true));
- }
- return super.equals(obj);
- }
-
- public static void setTrustBuiltIn(boolean trustBuiltIn) {
- if(trustBuiltIn) {
- if (!rootCAs.contains(builtIn)) {
- log.debug("Adding internal CA certificate: CN={}, O={} ({})",
- builtIn.getCommonName(), builtIn.getOrganization(), builtIn.getFingerprint());
- builtIn.rootCA = true;
- builtIn.valid = true;
- rootCAs.add(0, builtIn);
- }
- } else {
- if (rootCAs.contains(builtIn)) {
- log.debug("Removing internal CA certificate: CN={}, O={} ({})",
- builtIn.getCommonName(), builtIn.getOrganization(), builtIn.getFingerprint());
- rootCAs.remove(builtIn);
- }
- }
- Certificate.trustBuiltIn = trustBuiltIn;
- }
-
- public static boolean isTrustBuiltIn() {
- return trustBuiltIn;
- }
-
- public static boolean hasAdditionalCAs() {
- return rootCAs.size() > (isTrustBuiltIn() ? 1 : 0);
- }
-
- private static String getSubjectX509Principal(X509Certificate cert, ASN1ObjectIdentifier key) {
- try {
- Vector v = PrincipalUtil.getSubjectX509Principal(cert).getValues(key);
- if(v.size() > 0) {
- return String.valueOf(v.get(0));
- }
- } catch(CertificateEncodingException e) {
- log.warn("Certificate encoding exception occurred", e);
- }
- return "";
- }
-
-}
diff --git a/old code/tray/src/qz/auth/PairingAuth.java b/old code/tray/src/qz/auth/PairingAuth.java
deleted file mode 100755
index 9aff5c2..0000000
--- a/old code/tray/src/qz/auth/PairingAuth.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package qz.auth;
-
-import org.json.JSONObject;
-import qz.utils.FileUtilities;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import java.io.File;
-import java.io.FileReader;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.Base64;
-
-public class PairingAuth {
- private static String site = null;
- private static String pairingKey = null;
- private static final String HMAC_ALGO = "HmacSHA256";
- private static File configFile = null;
-
- static {
- loadConfig();
- }
-
- private static void loadConfig() {
- try {
- // Use QZ Tray's user directory - same location as PairingConfigDialog
- configFile = new File(FileUtilities.USER_DIR.toFile(), "pairing-config.json");
-
- if (!configFile.exists()) {
- System.out.println("Pairing config file not found at: " + configFile.getAbsolutePath());
- site = null;
- pairingKey = null;
- return;
- }
-
- String content = new String(Files.readAllBytes(configFile.toPath()));
- JSONObject config = new JSONObject(content);
- site = config.optString("site", null);
- pairingKey = config.optString("pairing_key", null);
-
- System.out.println("Pairing config loaded from: " + configFile.getAbsolutePath());
- System.out.println("Site configured: " + site);
- } catch (Exception e) {
- System.err.println("Error loading pairing config: " + e.getMessage());
- e.printStackTrace();
- site = null;
- pairingKey = null;
- }
- }
-
- public static String getSite() {
- return site;
- }
-
- public static String getPairingKey() {
- return pairingKey;
- }
-
- public static boolean isConfigured() {
- return site != null && !site.isEmpty() && pairingKey != null && !pairingKey.isEmpty();
- }
-
- public static String getConfigFilePath() {
- return configFile != null ? configFile.getAbsolutePath() : "unknown";
- }
-
- public static void reload() {
- loadConfig();
- }
-
- public static String hmacSignature(String message) {
- if (pairingKey == null || pairingKey.isEmpty()) {
- System.err.println("Cannot compute HMAC: pairing key is not configured");
- return null;
- }
- try {
- Mac mac = Mac.getInstance(HMAC_ALGO);
- SecretKeySpec keySpec = new SecretKeySpec(pairingKey.getBytes(StandardCharsets.UTF_8), HMAC_ALGO);
- mac.init(keySpec);
- byte[] hmac = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
- return Base64.getEncoder().encodeToString(hmac);
- } catch (Exception e) {
- System.err.println("HMAC computation failed: " + e.getMessage());
- return null;
- }
- }
-}
diff --git a/old code/tray/src/qz/auth/RequestState.java b/old code/tray/src/qz/auth/RequestState.java
deleted file mode 100755
index 0849c95..0000000
--- a/old code/tray/src/qz/auth/RequestState.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package qz.auth;
-
-import org.codehaus.jettison.json.JSONObject;
-import qz.common.Constants;
-
-import java.time.Instant;
-import java.util.Arrays;
-
-public class RequestState {
-
- public enum Validity {
- TRUSTED("Valid"),
- EXPIRED("Expired Signature"),
- UNSIGNED("Invalid Signature"),
- EXPIRED_CERT("Expired Certificate"),
- FUTURE_CERT("Future Certificate"),
- INVALID_CERT("Invalid Certificate"),
- UNKNOWN("Invalid");
-
- private String formatted;
-
- Validity(String formatted) {
- this.formatted = formatted;
- }
-
- public String getFormatted() {
- return formatted;
- }
- }
-
- Certificate certUsed;
- JSONObject requestData;
-
- boolean initialConnect;
- Validity status;
-
- public RequestState(Certificate cert, JSONObject data) {
- certUsed = cert;
- requestData = data;
- status = Validity.UNKNOWN;
- }
-
- public Certificate getCertUsed() {
- return certUsed;
- }
-
- public JSONObject getRequestData() {
- return requestData;
- }
-
- public boolean isInitialConnect() {
- return initialConnect;
- }
-
- public void markNewConnection(Certificate cert) {
- certUsed = cert;
- initialConnect = true;
-
- checkCertificateState(cert);
- }
-
- public void checkCertificateState(Certificate cert) {
- if (cert.isTrusted()) {
- status = Validity.TRUSTED;
- } else if (cert.getValidToDate().isBefore(Instant.now())) {
- status = Validity.EXPIRED_CERT;
- } else if (cert.getValidFromDate().isAfter(Instant.now())) {
- status = Validity.FUTURE_CERT;
- } else if (!cert.isValid()) {
- status = Validity.INVALID_CERT;
- } else {
- status = Validity.UNKNOWN;
- }
- }
-
- public Validity getStatus() {
- return status;
- }
-
- public void setStatus(Validity state) {
- status = state;
- }
-
- public boolean hasCertificate() {
- return certUsed != null && certUsed != Certificate.UNKNOWN;
- }
-
- public boolean hasSavedCert() {
- return isVerified() && certUsed.isSaved();
- }
-
- public boolean hasBlockedCert() {
- return certUsed == null || certUsed.isBlocked();
- }
-
- public String getCertName() {
- return certUsed.getCommonName();
- }
-
- public boolean isVerified() {
- return certUsed.isTrusted() && status == Validity.TRUSTED;
- }
-
- public boolean isSponsored() {
- return certUsed.isSponsored();
- }
-
- public String getValidityInfo() {
- if (status == Validity.TRUSTED) {
- return Constants.TRUSTED_CERT;
- } else if (Arrays.asList(Validity.UNSIGNED, Validity.EXPIRED, Validity.EXPIRED_CERT, Validity.FUTURE_CERT).contains(status)) {
- return Constants.NO_TRUST + " - " + status.getFormatted();
- } else {
- return Constants.UNTRUSTED_CERT;
- }
- }
-
-}
diff --git a/old code/tray/src/qz/auth/X509Constants.java b/old code/tray/src/qz/auth/X509Constants.java
deleted file mode 100755
index a923272..0000000
--- a/old code/tray/src/qz/auth/X509Constants.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package qz.auth;
-
-/**
- * Created by Tres on 3/3/2015.
- */
-public class X509Constants {
- public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
- public static final String END_CERT = "-----END CERTIFICATE-----";
- public static final String INTERMEDIATE_CERT = "--START INTERMEDIATE CERT--";
- public static final String BEGIN_CRL = "-----BEGIN X509 CRL-----";
- public static final String END_CRL = "-----END X509 CRL-----";
-}
diff --git a/old code/tray/src/qz/build/Fetcher.java b/old code/tray/src/qz/build/Fetcher.java
deleted file mode 100755
index db6edde..0000000
--- a/old code/tray/src/qz/build/Fetcher.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package qz.build;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import qz.utils.ShellUtilities;
-import qz.utils.SystemUtilities;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-/**
- * Fetches a zip or tarball from URL and decompresses it
- */
-public class Fetcher {
- public enum Format {
- ZIP(".zip"),
- TARBALL(".tar.gz"),
- UNKNOWN(null);
-
- String suffix;
- Format(String suffix) {
- this.suffix = suffix;
- }
-
- public String getSuffix() {
- return suffix;
- }
-
- public static Format parse(String url) {
- for(Format format : Format.values()) {
- if (url.endsWith(format.getSuffix())) {
- return format;
- }
- }
- return UNKNOWN;
- }
- }
-
- private static final Logger log = LogManager.getLogger(Fetcher.class);
-
- public static void main(String ... args) throws IOException {
- new Fetcher("jlink/qz-tray-src_x.x.x", "https://github.com/qzind/tray/archive/master.tar.gz").fetch().uncompress();
- }
-
- String resourceName;
- String url;
- Format format;
- Path rootDir;
- File tempArchive;
- File tempExtracted;
- File extracted;
-
- public Fetcher(String resourceName, String url) {
- this.url = url;
- this.resourceName = resourceName;
- this.format = Format.parse(url);
- // Try to calculate out/
- this.rootDir = SystemUtilities.getJarParentPath().getParent();
- }
-
- @SuppressWarnings("unused")
- public Fetcher(String resourceName, String url, Format format, String rootDir) {
- this.resourceName = resourceName;
- this.url = url;
- this.format = format;
- this.rootDir = Paths.get(rootDir);
- }
-
- public Fetcher fetch() throws IOException {
- extracted = new File(rootDir.toString(), resourceName);
- if(extracted.isDirectory() && extracted.exists()) {
- log.info("Resource '{}' from [{}] has already been downloaded and extracted. Using: [{}]", resourceName, url, extracted);
- } else {
- tempExtracted = new File(rootDir.toString(), resourceName + "~tmp");
- if(tempExtracted.exists()) {
- FileUtils.deleteDirectory(tempExtracted);
- }
- // temp directory to thwart partial extraction
- tempExtracted.mkdirs();
- tempArchive = File.createTempFile(resourceName, ".zip");
- log.info("Fetching '{}' from [{}] and saving to [{}]", resourceName, url, tempArchive);
- FileUtils.copyURLToFile(new URL(url), tempArchive);
- }
- return this;
- }
-
- public String uncompress() throws IOException {
- if(tempArchive != null) {
- log.info("Unzipping '{}' from [{}] to [{}]", resourceName, tempArchive, tempExtracted);
- if(format == Format.ZIP) {
- unzip(tempArchive.getAbsolutePath(), tempExtracted);
- } else {
- untar(tempArchive.getAbsolutePath(), tempExtracted);
- }
- log.info("Moving [{}] to [{}]", tempExtracted, extracted);
- tempExtracted.renameTo(extracted);
- }
- return extracted.toString();
- }
-
- public static void untar(String sourceFile, File targetDir) throws IOException {
- // TODO: Switch to TarArchiveInputStream from Apache Commons Compress
- if (!ShellUtilities.execute("tar", "-xzf", sourceFile, "-C", targetDir.getPath())) {
- throw new IOException("Something went wrong extracting " + sourceFile +", check logs for details");
- }
- }
-
- public static void unzip(String sourceFile, File targetDir) throws IOException {
- try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(sourceFile))) {
- for (ZipEntry ze; (ze = zipIn.getNextEntry()) != null; ) {
- Path resolvedPath = targetDir.toPath().resolve(ze.getName());
- if (ze.isDirectory()) {
- Files.createDirectories(resolvedPath);
- } else {
- Files.createDirectories(resolvedPath.getParent());
- Files.copy(zipIn, resolvedPath);
- }
- }
- }
- }
-}
diff --git a/old code/tray/src/qz/build/JLink.java b/old code/tray/src/qz/build/JLink.java
deleted file mode 100755
index b760c3c..0000000
--- a/old code/tray/src/qz/build/JLink.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/**
- * @author Tres Finocchiaro
- *
- * Copyright (C) 2020 Tres Finocchiaro, QZ Industries, LLC
- *
- * LGPL 2.1 This is free software. This software and source code are released under
- * the "LGPL 2.1 License". A copy of this license should be distributed with
- * this software. http://www.gnu.org/licenses/lgpl-2.1.html
- */
-
-package qz.build;
-
-import com.github.zafarkhaja.semver.Version;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import qz.build.jlink.Platform;
-import qz.build.jlink.Vendor;
-import qz.build.jlink.Url;
-import qz.build.provision.params.Arch;
-import qz.common.Constants;
-import qz.utils.*;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.file.*;
-import java.util.*;
-
-public class JLink {
- private static final Logger log = LogManager.getLogger(JLink.class);
- public static final Vendor JAVA_DEFAULT_VENDOR = Vendor.BELLSOFT;
- private static final String JAVA_DEFAULT_VERSION = "11.0.17+7";
- private static final String JAVA_DEFAULT_GC_ENGINE = "hotspot"; // or "openj9"
- private static final String JAVA_DEFAULT_GC_VERSION = "0.35.0"; // openj9 gc only
-
- private Path jarPath;
- private Path jdepsPath;
- private Path jlinkPath;
- private Path jmodsPath;
- private Path outPath;
- private Version jdepsVersion;
- private Platform hostPlatform;
- private Platform targetPlatform;
- private Arch hostArch;
- private Arch targetArch;
- private Vendor javaVendor;
- private String gcEngine;
- private String javaVersion;
- private String gcVersion;
-
- private Path targetJdk;
-
- private Version javaSemver;
-
- private LinkedHashSet depList;
-
- public JLink(String targetPlatform, String targetArch, String javaVendor, String javaVersion, String gcEngine, String gcVersion, String targetJdk) throws IOException {
- this.hostPlatform = Platform.getCurrentPlatform();
- this.hostArch = SystemUtilities.getArch();
-
- this.targetPlatform = Platform.parse(targetPlatform, this.hostPlatform);
- this.targetArch = Arch.parse(targetArch, this.hostArch);
- this.javaVendor = Vendor.parse(javaVendor, JAVA_DEFAULT_VENDOR);
- this.gcEngine = getParam("gcEngine", gcEngine, JAVA_DEFAULT_GC_ENGINE);
- this.javaVersion = getParam("javaVersion", javaVersion, JAVA_DEFAULT_VERSION);
- this.gcVersion = getParam("gcVersion", gcVersion, JAVA_DEFAULT_GC_VERSION);
-
- this.javaSemver = SystemUtilities.getJavaVersion(this.javaVersion);
-
- // Optional: Provide the location of a custom JDK on the local filesystem
- if(!StringUtils.isEmpty(targetJdk)) {
- Path jdkPath = Paths.get(targetJdk);
- Properties jdkProps = new Properties();
- jdkProps.load(new FileInputStream(jdkPath.resolve("release").toFile()));
- String customVersion = jdkProps.getProperty("JAVA_VERSION");
- if(customVersion.contains("\"")) {
- customVersion = customVersion.split("\"")[1];
- }
- Version customSemver = SystemUtilities.getJavaVersion(customVersion);
- if(needsDownload(javaSemver, customSemver)) {
- // The "release" file doesn't have build info, so we can't auto-download :(
- if(javaSemver.getMajorVersion() != customSemver.getMajorVersion()) {
- log.error("Error: jlink version {}.0 does not match target java.base version {}.0", javaSemver.getMajorVersion(), customSemver.getMajorVersion());
- } else {
- // Handle edge-cases (e.g. JDK-8240734)
- log.error("Error: jlink version {} is incompatible with target java.base version {}", javaSemver.getMajorVersion(), customSemver.getMajorVersion());
- }
- System.exit(2);
- }
- this.targetJdk = Paths.get(targetJdk);
- calculateToolPaths(Paths.get(targetJdk));
- } else {
- // Determine if the version we're building with is compatible with the target version
- if (needsDownload(javaSemver, Constants.JAVA_VERSION)) {
- log.warn("Java versions are incompatible, locating a suitable runtime for Java " + javaSemver.getMajorVersion() + "...");
- String hostJdk = downloadJdk(this.hostArch, this.hostPlatform);
- calculateToolPaths(Paths.get(hostJdk));
- } else {
- calculateToolPaths(null);
- }
- }
-
- if(this.targetJdk == null) {
- targetJdk = downloadJdk(this.targetArch, this.targetPlatform);
- jmodsPath = Paths.get(targetJdk, "jmods");
- } else {
- log.info("\"targetjdk\" was provided {}, skipping download", targetJdk);
- jmodsPath = this.targetJdk.resolve("jmods");
- }
-
- log.info("Selecting jmods folder: {}", jmodsPath);
-
- calculateJarPath()
- .calculateOutPath()
- .calculateDepList()
- .deployJre();
- }
-
- public static void main(String ... args) throws IOException {
- new JLink(null, null, null, null, null, null, null).calculateJarPath();
- }
-
- /**
- * Handle incompatibilities between JDKs, download a fresh one if needed
- */
- private static boolean needsDownload(Version want, Version installed) {
- // jdeps and jlink historically require matching major JDK versions. Download if needed.
- boolean downloadJdk = installed.getMajorVersion() != want.getMajorVersion();
-
- // Per JDK-8240734: Major versions checks aren't enough starting with 11.0.16+8
- // see also https://github.com/adoptium/adoptium-support/issues/557
- Version bad = SystemUtilities.getJavaVersion("11.0.16+8");
- if(want.greaterThanOrEqualTo(bad) && installed.lessThan(bad) ||
- installed.greaterThanOrEqualTo(bad) && want.lessThan(bad)) {
- // Force download
- // Fixes "Hash of java.rmi differs from expected hash"
- downloadJdk = true;
- }
- return downloadJdk;
- }
-
- /**
- * Download the JDK and return the path it was extracted to
- */
- private String downloadJdk(Arch arch, Platform platform) throws IOException {
- String url = new Url(this.javaVendor).format(arch, platform, this.gcEngine, this.javaSemver, this.javaVersion, this.gcVersion);
-
- // Saves to out e.g. "out/jlink/jdk-AdoptOpenjdk-amd64-platform-11_0_7"
- String extractedJdk = new Fetcher(String.format("jlink/jdk-%s-%s-%s-%s", javaVendor.value(), arch, platform.value(), javaSemver.toString().replaceAll("\\+", "_")), url)
- .fetch()
- .uncompress();
-
- // Get first subfolder, e.g. jdk-11.0.7+10
- for(File subfolder : new File(extractedJdk).listFiles(pathname -> pathname.isDirectory())) {
- extractedJdk = subfolder.getPath();
- if(platform == Platform.MAC && Paths.get(extractedJdk, "/Contents/Home").toFile().isDirectory()) {
- extractedJdk += "/Contents/Home";
- }
- log.info("Selecting JDK home: {}", extractedJdk);
- break;
- }
-
- return extractedJdk;
- }
-
- private JLink calculateJarPath() {
- if(SystemUtilities.isJar()) {
- jarPath = SystemUtilities.getJarPath();
- } else {
- // Detect out/dist/qz-tray.jar for IDE usage
- jarPath = SystemUtilities.getJarParentPath()
- .resolve("dist")
- .resolve(Constants.PROPS_FILE + ".jar");
- }
- log.info("Assuming jar path: {}", jarPath);
- return this;
- }
-
- private JLink calculateOutPath() {
- switch(targetPlatform) {
- case MAC:
- outPath = jarPath.resolve("../Java.runtime/Contents/Home").normalize();
- break;
- default:
- outPath = jarPath.resolve("../runtime").normalize();
- }
- log.info("Assuming output path: {}", outPath);
- return this;
- }
-
- private JLink calculateToolPaths(Path javaHome) throws IOException {
- if(javaHome == null) {
- javaHome = Paths.get(System.getProperty("java.home"));
- }
- log.info("Using JAVA_HOME: {}", javaHome);
- jdepsPath = javaHome.resolve("bin").resolve(SystemUtilities.isWindows() ? "jdeps.exe" : "jdeps").normalize();
- jlinkPath = javaHome.resolve("bin").resolve(SystemUtilities.isWindows() ? "jlink.exe" : "jlink").normalize();
- log.info("Assuming jdeps path: {}", jdepsPath);
- log.info("Assuming jlink path: {}", jlinkPath);
- jdepsPath.toFile().setExecutable(true, false);
- jlinkPath.toFile().setExecutable(true, false);
- jdepsVersion = SystemUtilities.getJavaVersion(jdepsPath);
- return this;
- }
-
- private JLink calculateDepList() throws IOException {
- log.info("Calling jdeps to determine runtime dependencies");
- depList = new LinkedHashSet<>();
-
- // JDK11.0.11+requires suppressing of missing deps
- String raw = jdepsVersion.compareTo(Version.valueOf("11.0.10")) > 0 ?
- ShellUtilities.executeRaw(jdepsPath.toString(), "--multi-release", "9", "--list-deps", "--ignore-missing-deps", jarPath.toString()) :
- ShellUtilities.executeRaw(jdepsPath.toString(), "--multi-release", "9", "--list-deps", jarPath.toString());
- if (raw == null || raw.trim().isEmpty() || raw.trim().startsWith("Warning") ) {
- throw new IOException("An unexpected error occurred calling jdeps. Please check the logs for details.\n" + raw);
- }
- for(String item : raw.split("\\r?\\n")) {
- item = item.trim();
- if(!item.isEmpty()) {
- if(item.startsWith("JDK") || item.startsWith("jdk8internals")) {
- // Remove e.g. "JDK removed internal API/sun.reflect"
- log.trace("Removing dependency: '{}'", item);
- continue;
- }
- if(item.contains("/")) {
- // Isolate base name e.g. "java.base/com.sun.net.ssl"
- item = item.split("/")[0];
- }
- depList.add(item);
- }
- }
- switch(targetPlatform) {
- case WINDOWS:
- // Java accessibility bridge dependency, see https://github.com/qzind/tray/issues/1234
- depList.add("jdk.accessibility");
- default:
- // Adds "bin/jcmd"
- depList.add("jdk.jcmd");
- // "jar:" URLs create transient zipfs dependency, see https://stackoverflow.com/a/57846672/3196753
- depList.add("jdk.zipfs");
- // fix for https://github.com/qzind/tray/issues/894 solution from https://github.com/adoptium/adoptium-support/issues/397
- depList.add("jdk.crypto.ec");
- }
- return this;
- }
-
- private JLink deployJre() throws IOException {
- if(targetPlatform == Platform.MAC) {
- // Deploy Contents/MacOS/libjli.dylib
- Path macOS = Files.createDirectories(outPath.resolve("../MacOS").normalize());
- Path jliLib = macOS.resolve("libjli.dylib");
- log.info("Deploying {}", macOS);
- try {
- // Not all jdks use a bundle format, but try this first
- Files.copy(jmodsPath.resolve("../../MacOS/libjli.dylib").normalize(), jliLib, StandardCopyOption.REPLACE_EXISTING);
- } catch(IOException ignore) {
- // Fallback to flat format
- String libjli = "../lib/jli/libjli.dylib";
- if(javaSemver.getMajorVersion() >= 21) {
- libjli = "../lib/libjli.dylib";
- }
- Files.copy(jmodsPath.resolve(libjli).normalize(), jliLib, StandardCopyOption.REPLACE_EXISTING);
- }
-
- // Deploy Contents/Info.plist
- HashMap fieldMap = new HashMap<>();
- fieldMap.put("%BUNDLE_ID%", MacUtilities.getBundleId() + ".jre"); // e.g. io.qz.qz-tray.jre
- fieldMap.put("%BUNDLE_VERSION%", String.format("%s.%s.%s", javaSemver.getMajorVersion(), javaSemver.getMinorVersion(), javaSemver.getPatchVersion()));
- fieldMap.put("%BUNDLE_VERSION_FULL%", javaSemver.toString());
- fieldMap.put("%BUNDLE_VENDOR%", javaVendor.getVendorName());
- fieldMap.put("%BUNDLE_PRODUCT%", javaVendor.getProductName());
- log.info("Deploying {}/Info.plist", macOS.getParent());
- FileUtilities.configureAssetFile("assets/mac-runtime.plist.in", macOS.getParent().resolve("Info.plist"), fieldMap, JLink.class);
- }
-
- FileUtils.deleteQuietly(outPath.toFile());
-
- if(ShellUtilities.execute(jlinkPath.toString(),
- "--strip-debug",
- "--compress=2",
- "--no-header-files",
- "--no-man-pages",
- "--exclude-files=glob:**/legal/**",
- "--module-path", jmodsPath.toString(),
- "--add-modules", String.join(",", depList),
- "--output", outPath.toString())) {
- log.info("Successfully deployed a jre to {}", outPath);
-
- // Remove all but java/javaw
- List keepFiles = new ArrayList<>();
- //String[] keepFiles;
- String keepExt;
- switch(targetPlatform) {
- case WINDOWS:
- keepFiles.add("java.exe");
- keepFiles.add("javaw.exe");
- keepFiles.add("jcmd.exe");
- if(depList.contains("jdk.accessibility")) {
- // Java accessibility bridge switching tool
- keepFiles.add("jabswitch.exe");
- }
- // Windows stores ".dll" files in bin
- keepExt = ".dll";
- break;
- default:
- keepFiles.add("java");
- keepFiles.add("jcmd");
- keepExt = null;
- }
-
- Files.list(outPath.resolve("bin")).forEach(binFile -> {
- if(Files.isDirectory(binFile) || (keepExt != null && binFile.toString().endsWith(keepExt))) {
- log.info("Keeping {}", binFile);
- return; // iterate forEach
- }
- for(String name : keepFiles) {
- if (binFile.endsWith(name)) {
- log.info("Keeping {}", binFile);
- return; // iterate forEach
- }
- }
- log.info("Deleting {}", binFile);
- binFile.toFile().delete();
- });
-
- return this;
-
- }
- throw new IOException("An error occurred deploying the jre. Please check the logs for details.");
- }
-
- public static String getParam(String paramName, String value, String fallback) {
- if(value != null && !value.isEmpty() && !value.trim().isEmpty()) {
- return value;
- }
- log.info("No {} specified, assuming '{}'", paramName, fallback);
- return fallback;
- }
-}
diff --git a/old code/tray/src/qz/build/assets/mac-runtime.plist.in b/old code/tray/src/qz/build/assets/mac-runtime.plist.in
deleted file mode 100755
index c02ba7f..0000000
--- a/old code/tray/src/qz/build/assets/mac-runtime.plist.in
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- English
- CFBundleExecutable
- libjli.dylib
- CFBundleGetInfoString
- %BUNDLE_VENDOR% %BUNDLE_PRODUCT% %BUNDLE_VERSION_FULL%
- CFBundleIdentifier
- %BUNDLE_ID%
- CFBundleInfoDictionaryVersion
- 7.0
- CFBundleName
- Java Runtime Image
- CFBundlePackageType
- BNDL
- CFBundleShortVersionString
- %BUNDLE_VERSION%
- CFBundleSignature
- ????
- CFBundleVersion
- %BUNDLE_VERSION%
- JavaVM
-
- JVMCapabilities
-
- CommandLine
- JNI
- BundledApp
-
- JVMMinimumFrameworkVersion
- 17.0.0
- JVMMinimumSystemVersion
- 10.6.0
- JVMPlatformVersion
- %BUNDLE_VERSION_FULL%
- JVMVendor
- %BUNDLE_VENDOR%
- JVMVersion
- %BUNDLE_VERSION%
-
-
-
diff --git a/old code/tray/src/qz/build/jlink/Arch.java b/old code/tray/src/qz/build/jlink/Arch.java
deleted file mode 100755
index e69de29..0000000
diff --git a/old code/tray/src/qz/build/jlink/Parsable.java b/old code/tray/src/qz/build/jlink/Parsable.java
deleted file mode 100755
index 94eddf4..0000000
--- a/old code/tray/src/qz/build/jlink/Parsable.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package qz.build.jlink;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.lang.reflect.Field;
-import java.util.Locale;
-
-/**
- * A special template class for handling enums with varargs needing string matches.
- *
- * Parsable enums must declare public static void String[] matches;
- * in the constructor, which parse(Class enumType,
String value) will
- * call using reflection.
- *
- * Enums are inherently static in Java and cannot extend superclasses. The
- * workaround to avoid code duplication is to leverage reflection and generics in
- * static utility functions.
- *
- * The downsides of this are:
- * - Reflection is slow
- * - Static helpers must be explicitly class-type-aware*
- *
- * *Non-static methods may be implicit, but create anti-patterns for static helpers
- * such as parse(String value) as they would exist at
- * ENUM_ENTRY.parse(...) rather than EnumClass.parse(...).
- */
-public interface Parsable {
- Logger log = LogManager.getLogger(Parsable.class);
-
- static > T parse(Class enumType, String value) {
- if(value != null && !value.trim().isEmpty()) {
- for(T parsable : enumType.getEnumConstants()) {
- try {
- Field matchesField = parsable.getClass().getDeclaredField("matches");
- String[] matches = (String[])matchesField.get(parsable);
- for(String match : matches) {
- if (match.equalsIgnoreCase(value)) {
- return parsable;
- }
- }
- } catch(NoSuchFieldException | IllegalAccessException | ClassCastException e) {
- log.warn("Parsable enums must have a 'public String[] matches' field", e);
- }
- }
- }
- log.warn("Could not parse {} as a valid {} value", value, enumType.getSimpleName());
- return null;
- }
-
- static > T parse(Class enumType, String value, T fallback, boolean silent) {
- if(value != null && !value.trim().isEmpty()) {
- return parse(enumType, value);
- }
- if(!silent) {
- log.warn("No {} specified, assuming '{}'", enumType.getSimpleName(), ((Parsable)fallback).value());
- }
- return fallback;
- }
-
- static > T parse(Class enumType, String value, T fallback) {
- return parse(enumType, value, fallback, false);
- }
-
- default String value() {
- return ((T)this).toString().toLowerCase(Locale.ENGLISH);
- }
-}
diff --git a/old code/tray/src/qz/build/jlink/Platform.java b/old code/tray/src/qz/build/jlink/Platform.java
deleted file mode 100755
index 87149ce..0000000
--- a/old code/tray/src/qz/build/jlink/Platform.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package qz.build.jlink;
-
-
-import qz.utils.SystemUtilities;
-
-/**
- * Handling of platform names as they would appear in a URL
- * Values added must also be added to ArgValue.JLINK --platform values
- */
-public enum Platform implements Parsable {
- MAC("mac"),
- WINDOWS("windows"),
- LINUX("linux");
-
- public final String[] matches;
- Platform(String ... matches) { this.matches = matches; }
-
- public static Platform parse(String value, Platform fallback) {
- return Parsable.parse(Platform.class, value, fallback);
- }
-
- public static Platform parse(String value) {
- return Parsable.parse(Platform.class, value);
- }
-
- public static Platform getCurrentPlatform() {
- switch(SystemUtilities.getOs()) {
- case MAC:
- return Platform.MAC;
- case WINDOWS:
- return Platform.WINDOWS;
- case LINUX:
- default:
- return Platform.LINUX;
- }
- }
-}
diff --git a/old code/tray/src/qz/build/jlink/Url.java b/old code/tray/src/qz/build/jlink/Url.java
deleted file mode 100755
index 11cf0e3..0000000
--- a/old code/tray/src/qz/build/jlink/Url.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package qz.build.jlink;
-
-import com.github.zafarkhaja.semver.Version;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import qz.build.provision.params.Arch;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.HashMap;
-
-import static qz.build.jlink.Vendor.*;
-
-/**
- * Each JDK provider uses their own url format
- */
-public class Url {
- static HashMap VENDOR_URL_MAP = new HashMap<>();
- static {
- VENDOR_URL_MAP.put(BELLSOFT, "https://download.bell-sw.com/java/%s/bellsoft-jdk%s-%s-%s.%s");
- VENDOR_URL_MAP.put(ECLIPSE, "https://github.com/adoptium/temurin%s-binaries/releases/download/jdk-%s/OpenJDK%sU-jdk_%s_%s_%s_%s.%s");
- VENDOR_URL_MAP.put(IBM, "https://github.com/ibmruntimes/semeru%s-binaries/releases/download/jdk-%s_%s-%s/ibm-semeru-open-jdk_%s_%s_%s_%s-%s.%s");
- VENDOR_URL_MAP.put(MICROSOFT, "https://aka.ms/download-jdk/microsoft-jdk-%s-%s-%s.%s");
- VENDOR_URL_MAP.put(AMAZON, "https://corretto.aws/downloads/resources/%s/amazon-corretto-%s-%s-%s.%s");
- VENDOR_URL_MAP.put(AZUL, "https://cdn.azul.com/zulu%s/bin/zulu%s-ca-jdk%s-%s_%s.%s");
- }
-
- private static final Logger log = LogManager.getLogger(Url.class);
-
- Vendor vendor;
- String pattern;
- public Url(Vendor vendor) {
- this.vendor = vendor;
- if(!VENDOR_URL_MAP.containsKey(vendor)) {
- throw new UnsupportedOperationException(String.format("Vendor provided '%s' couldn't be matched to a URL pattern, aborting.", vendor));
- }
- pattern = VENDOR_URL_MAP.get(vendor);
- }
-
- public String format(Arch arch, Platform platform, String gcEngine, Version javaSemver, String javaVersion, String gcVer) throws UnsupportedEncodingException {
- Url pattern = new Url(vendor);
- String urlArch = vendor.getUrlArch(arch);
- String fileExt = vendor.getUrlExtension(platform);
- String urlPlatform = vendor.getUrlPlatform(platform);
- String urlJavaVersion = vendor.getUrlJavaVersion(javaSemver);
-
- // Convert "+" to "%2B"
- String urlJavaVersionEncode = URLEncoder.encode(javaVersion, "UTF-8");
-
- int javaMajor = javaSemver.getMajorVersion();
-
- switch(vendor) {
- case BELLSOFT:
- return String.format(pattern.pattern, urlJavaVersionEncode, urlJavaVersionEncode, urlPlatform, urlArch, fileExt);
- case ECLIPSE:
- return String.format(pattern.pattern, javaMajor, urlJavaVersionEncode, javaMajor, urlArch, urlPlatform, gcEngine, urlJavaVersion, fileExt);
- case IBM:
- return String.format(pattern.pattern, javaMajor, urlJavaVersionEncode, gcEngine, gcVer, urlArch, urlPlatform, urlJavaVersion, gcEngine, gcVer, fileExt);
- case MICROSOFT:
- return String.format(pattern.pattern, urlJavaVersion, urlPlatform, urlArch, fileExt);
- case AMAZON:
- return String.format(pattern.pattern, urlJavaVersion, urlJavaVersion, urlPlatform, urlArch, fileExt);
- case AZUL:
- // Special handling of Linux aarch64
- String embedded = platform == Platform.LINUX ? "-embedded" : "";
- return String.format(pattern.pattern, embedded, gcVer, urlJavaVersion, urlPlatform, urlArch, fileExt);
- default:
- throw new UnsupportedOperationException(String.format("URL pattern for '%s' (%s) is missing a format implementation.", vendor, pattern));
- }
- }
-
-}
diff --git a/old code/tray/src/qz/build/jlink/Vendor.java b/old code/tray/src/qz/build/jlink/Vendor.java
deleted file mode 100755
index 7405e6b..0000000
--- a/old code/tray/src/qz/build/jlink/Vendor.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package qz.build.jlink;
-
-import com.github.zafarkhaja.semver.Version;
-import qz.build.provision.params.Arch;
-
-/**
- * Handling of java vendors
- */
-public enum Vendor implements Parsable {
- ECLIPSE("Eclipse", "Adoptium", "adoptium", "temurin", "adoptopenjdk"),
- BELLSOFT("BellSoft", "Liberica", "bellsoft", "liberica"),
- IBM("IBM", "Semeru", "ibm", "semeru"),
- MICROSOFT("Microsoft", "OpenJDK", "microsoft"),
- AMAZON("Amazon", "Corretto", "amazon", "corretto"),
- AZUL("Azul", "Zulu", "azul", "zulu");
-
- public String vendorName;
- public String productName;
- public final String[] matches;
- Vendor(String vendorName, String productName, String ... matches) {
- this.matches = matches;
- this.vendorName = vendorName;
- this.productName = productName;
- }
-
- public static Vendor parse(String value, Vendor fallback) {
- return Parsable.parse(Vendor.class, value, fallback, true);
- }
-
- public static Vendor parse(String value) {
- return Parsable.parse(Vendor.class, value);
- }
-
- public String getVendorName() {
- return vendorName;
- }
-
- public String getProductName() {
- return productName;
- }
-
- /**
- * Map Vendor to Arch value
- */
- public String getUrlArch(Arch arch) {
- switch(arch) {
- case AARCH64:
- // All vendors seem to use "aarch64" universally
- return "aarch64";
- case ARM32:
- switch(this) {
- case BELLSOFT:
- return "arm32-vfp-hflt";
- case AZUL:
- return "aarch32hf";
- case MICROSOFT:
- case IBM:
- throw new UnsupportedOperationException("Vendor does not provide builds for this architecture");
- case AMAZON:
- case ECLIPSE:
- default:
- return "arm";
- }
- case RISCV64:
- return "riscv64";
- case X86:
- switch(this) {
- case AZUL:
- return "i686";
- case BELLSOFT:
- return "i586";
- case ECLIPSE:
- case IBM:
- return "x86-32";
- case AMAZON:
- default:
- return "x86";
- }
- case X86_64:
- default:
- switch(this) {
- // BellSoft uses "amd64"
- case BELLSOFT:
- return "amd64";
- }
- return "x64";
- }
- }
-
- /**
- * Map Vendor to Platform name
- */
- public String getUrlPlatform(Platform platform) {
- switch(platform) {
- case MAC:
- switch(this) {
- case BELLSOFT:
- return "macos";
- case MICROSOFT:
- return "macOS";
- case AMAZON:
- case AZUL:
- return "macosx";
- }
- default:
- return platform.value();
- }
- }
-
- /**
- * Map Vendor and Platform to file extension
- */
- public String getUrlExtension(Platform platform) {
- switch(this) {
- case BELLSOFT:
- switch(platform) {
- case LINUX:
- return "tar.gz";
- default:
- // BellSoft uses "zip" for mac and windows platforms
- return "zip";
- }
- default:
- switch(platform) {
- case WINDOWS:
- return "zip";
- default:
- return "tar.gz";
- }
- }
- }
-
- public String getUrlJavaVersion(Version javaSemver) {
- switch(this) {
- case MICROSOFT:
- case AZUL:
- // Return shorted version (Microsoft, Azul suppresses the build information from URLs)
- return javaSemver.toString().split("\\+")[0];
- case AMAZON:
- // Return lengthened version (Corretto formats major.minor.patch.build.number, e.g. 11.0.17.8.1)
- String[] parts = javaSemver.toString().split("\\+");
- String javaVersion = parts[0];
- //
- String buildAndNumber = parts[1];
- if(!buildAndNumber.contains(".")) {
- // Append ".1" if ".number" is missing
- buildAndNumber += ".1";
- }
- return String.format("%s.%s", javaVersion, buildAndNumber);
- }
- // All others seem to prefer "+" replaced with "_"
- return javaSemver.toString().replaceAll("\\+", "_");
- }
-}
-
diff --git a/old code/tray/src/qz/build/provision/ProvisionBuilder.java b/old code/tray/src/qz/build/provision/ProvisionBuilder.java
deleted file mode 100755
index 95b6145..0000000
--- a/old code/tray/src/qz/build/provision/ProvisionBuilder.java
+++ /dev/null
@@ -1,328 +0,0 @@
-package qz.build.provision;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import qz.build.provision.params.Arch;
-import qz.build.provision.params.Os;
-import qz.build.provision.params.Phase;
-import qz.build.provision.params.Type;
-import qz.common.Constants;
-import qz.installer.provision.invoker.PropertyInvoker;
-import qz.utils.ArgValue;
-import qz.utils.SystemUtilities;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class ProvisionBuilder {
- protected static final Logger log = LogManager.getLogger(ProvisionBuilder.class);
-
- public static final Path BUILD_PROVISION_FOLDER = SystemUtilities.getJarParentPath().resolve(Constants.PROVISION_DIR);
- public static final File BUILD_PROVISION_FILE = BUILD_PROVISION_FOLDER.resolve(Constants.PROVISION_FILE).toFile();
-
- private File ingestFile;
- private JSONArray jsonSteps;
- private Arch targetArch;
- private Os targetOs;
-
- /**
- * Parses command line input to create a "provision" folder in the dist directory for customizing the installation or startup
- */
- public ProvisionBuilder(String type, String phase, String os, String arch, String data, String args, String description, String ... varArgs) throws IOException, JSONException {
- createProvisionDirectory(false);
-
- targetOs = Os.ALL;
- targetArch = Arch.ALL;
- jsonSteps = new JSONArray();
-
- // Wrap into JSON so that we can save it
- JSONObject jsonStep = new JSONObject();
- putPattern(jsonStep, "description", description);
- putPattern(jsonStep, "type", type);
- putPattern(jsonStep, "phase", phase);
- putPattern(jsonStep, "os", os);
- putPattern(jsonStep, "arch", arch);
- putPattern(jsonStep, "data", data);
- putPattern(jsonStep, "args", args);
- putPattern(jsonStep, "arg%d", varArgs);
-
- // Command line invocation, use the working directory
- Path relativePath = Paths.get(System.getProperty("user.dir"));
- ingestStep(jsonStep, relativePath);
- }
-
- /**
- * To be called by ant's provision target
- */
- public ProvisionBuilder(File antJsonFile, String antTargetOs, String antTargetArch) throws IOException, JSONException {
- createProvisionDirectory(true);
-
- // Calculate the target os, architecture
- this.targetArch = Arch.parseStrict(antTargetArch);
- this.targetOs = Os.parseStrict(antTargetOs);
-
- this.jsonSteps = new JSONArray();
- this.ingestFile = antJsonFile;
-
- String jsonData = FileUtils.readFileToString(antJsonFile, StandardCharsets.UTF_8);
- JSONArray pendingSteps = new JSONArray(jsonData);
-
- // Cycle through so that each Step can be individually processed
- Path relativePath = antJsonFile.toPath().getParent();
- for(int i = 0; i < pendingSteps.length(); i++) {
- JSONObject jsonStep = pendingSteps.getJSONObject(i);
- System.out.println();
- try {
- ingestStep(jsonStep, relativePath);
- } catch(Exception e) {
- log.warn("[SKIPPED] Step '{}'", jsonStep, e);
- }
- }
-
- }
-
- public JSONArray getJson() {
- return jsonSteps;
- }
-
- /**
- * Construct as a Step to perform basic parsing/sanity checks
- * Copy resources (if needed) to provisioning directory
- */
- private void ingestStep(JSONObject jsonStep, Path relativePath) throws JSONException, IOException {
- Step step = Step.parse(jsonStep, relativePath);
- if(!targetOs.matches(step.os)) {
- log.info("[SKIPPED] Os '{}' does not match target Os '{}' '{}'", Os.serialize(step.os), targetOs, step);
- return;
- }
-
- if(!targetArch.matches(step.arch)) {
- log.info("[SKIPPED] Arch '{}' does not match target Os '{}' '{}'", Arch.serialize(step.arch), targetArch, step);
- return;
- }
-
- // Inject any special inferences (such as inferring resources from args)
- inferAdditionalSteps(step);
-
- if(copyResource(step)) {
- log.info("[SUCCESS] Step successfully processed '{}'", step);
- jsonSteps.put(step.toJSON());
- // Special case for custom websocket ports
- if(step.getType() == Type.PROPERTY && step.getPhase() == Phase.CERTGEN) {
- HashMap pairs = PropertyInvoker.parsePropertyPairs(step);
- if(pairs.get(ArgValue.WEBSOCKET_SECURE_PORTS.getMatch()) != null ||
- pairs.get(ArgValue.WEBSOCKET_INSECURE_PORTS.getMatch()) != null) {
- // Clone to install step
- jsonSteps.put(step.cloneTo(Phase.INSTALL).toJSON());
- }
- }
- } else {
- log.error("[SKIPPED] Resources could not be saved '{}'", step);
- }
- }
-
- /**
- * Save any resources files required for INSTALL and SCRIPT steps to provision folder
- */
- public boolean copyResource(Step step) throws IOException {
- switch(step.getType()) {
- case CA:
- case CERT:
- case SCRIPT:
- case RESOURCE:
- case SOFTWARE:
- boolean isRelative = !Paths.get(step.getData()).isAbsolute();
- File src;
- if(isRelative) {
- if(ingestFile != null) {
- Path parentDir = ingestFile.getParentFile().toPath();
- src = parentDir.resolve(step.getData()).toFile();
- } else {
- throw formatted("Unable to resolve path: '%s' '%s'", step.getData(), step);
- }
- } else {
- src = new File(step.getData());
- }
- String fileName = src.getName();
- if(fileName.equals(BUILD_PROVISION_FILE.getName())) {
- throw formatted("Resource name conflicts with provision file '%s' '%s'", fileName, step);
- }
- File dest = BUILD_PROVISION_FOLDER.resolve(fileName).toFile();
- int i = 0;
- // Avoid conflicting file names
- String name = dest.getName();
-
- // Avoid resource clobbering when being invoked by command line or providing certificates.
- // Otherwise, assume the intent is to re-use the same resource (e.g. "my_script.sh", etc)
- if(ingestFile == null || step.getType() == Type.CERT) {
- while(dest.exists()) {
- // Append "filename-1.txt" until there's no longer a conflict
- if (name.contains(".")) {
- dest = BUILD_PROVISION_FOLDER.resolve(String.format("%s-%s.%s", FilenameUtils.removeExtension(name), ++i,
- FilenameUtils.getExtension(name))).toFile();
- } else {
- dest = BUILD_PROVISION_FOLDER.resolve(String.format("%-%", name, ++i)).toFile();
- }
- }
- }
-
- FileUtils.copyFile(src, dest);
- if(dest.exists()) {
- step.setData(BUILD_PROVISION_FOLDER.relativize(dest.toPath()).toString());
- } else {
- return false;
- }
- break;
- default:
- }
- return true;
- }
-
- /**
- * Appends the JSONObject to the end of the provisionFile
- */
- public boolean saveJson(boolean overwrite) throws IOException, JSONException {
- // Read existing JSON file if exists
- JSONArray mergeSteps;
- if(!overwrite && BUILD_PROVISION_FILE.exists()) {
- String jsonData = FileUtils.readFileToString(BUILD_PROVISION_FILE, StandardCharsets.UTF_8);
- mergeSteps = new JSONArray(jsonData);
- } else {
- mergeSteps = new JSONArray();
- }
-
- // Merge in new steps
- for(int i = 0; i < jsonSteps.length(); i++) {
- mergeSteps.put(jsonSteps.getJSONObject(i));
- }
-
- FileUtils.writeStringToFile(BUILD_PROVISION_FILE, mergeSteps.toString(3), StandardCharsets.UTF_8);
- return true;
- }
-
- /**
- * Convenience method for adding a name/value pair into the JSONObject
- */
- private static void putPattern(JSONObject jsonStep, String name, String val) throws JSONException {
- if(val != null && !val.isEmpty()) {
- jsonStep.put(name, val);
- }
- }
-
- /**
- * Convenience method for adding consecutive patterned value pairs into the JSONObject
- * e.g. --arg1 "foo" --arg2 "bar"
- */
- private static void putPattern(JSONObject jsonStep, String pattern, String ... varArgs) throws JSONException {
- int argCounter = 0;
- for(String arg : varArgs) {
- jsonStep.put(String.format(pattern, ++argCounter), arg);
- }
- }
-
- private static void createProvisionDirectory(boolean cleanDirectory) throws IOException {
- if(cleanDirectory) {
- FileUtils.deleteDirectory(BUILD_PROVISION_FOLDER.toFile());
- }
- if(BUILD_PROVISION_FOLDER.toFile().isDirectory()) {
- return;
- }
- if(BUILD_PROVISION_FOLDER.toFile().mkdirs()) {
- return;
- }
- throw formatted("Could not create provision destination: '%'", BUILD_PROVISION_FOLDER);
- }
-
- private static IOException formatted(String message, Object ... args) {
- String formatted = String.format(message, args);
- return new IOException(formatted);
- }
-
- /**
- * Returns the first index of the specified arg prefix pattern(s)
- *
- * e.g. if pattern is "/f1", it will return 1 from args { "/s", "/f1C:\foo" }
- */
- private int argPrefixIndex(Step step, String ... prefixes) {
- for(int i = 0; i < step.args.size() ; i++){
- for(String prefix : prefixes) {
- if (step.args.get(i).toLowerCase().startsWith(prefix.toLowerCase())) {
- return i;
- }
- }
- }
- return -1;
- }
-
- /**
- * Returns the "value" of the specified arg prefix pattern(s)
- *
- * e.g. if pattern is "/f1", it will return "C:\foo" from args { "/s", "/f1C:\foo" }
- *
- */
- private String argPrefixValue(Step step, int index, String ... prefixes) {
- String arg = step.args.get(index);
- String value = null;
- for(String prefix : prefixes) {
- if (arg.toLowerCase().startsWith(prefix.toLowerCase())) {
- value = arg.substring(prefix.length());
- if((value.startsWith("\"") && value.endsWith("\"")) ||
- (value.startsWith("'") && value.endsWith("'"))) {
- // Remove surrounding quotes
- value = value.substring(1, value.length() - 1);
- }
- }
- }
- return value;
- }
-
- /**
- * Clones the provided step into a new step that performs a prerequisite task.
- *
- * This is "magic" in the sense that it's highly specific to Type
- * Os and Step.args.
- *
- * For example:
- *
- * Older InstallShield installers supported the /f1 parameter which
- * implies an answer file of which we need to bundle for a successful deployment.
- */
- private void inferAdditionalSteps(Step orig) throws JSONException, IOException {
- // Infer resource step for InstallShield .iss answer files
- if(orig.getType() == Type.SOFTWARE && Os.WINDOWS.matches(orig.getOs())) {
- String[] patterns = { "/f1", "-f1" };
- int index = argPrefixIndex(orig, patterns);
- if(index > 0) {
- String resource = argPrefixValue(orig, index, patterns);
- if(resource != null) {
- // Clone to copy the Phase, Os and Description
- Step step = orig.clone();
-
- // Swap Type, clear args and update the data
- step.setType(Type.RESOURCE);
- step.setArgs(new ArrayList<>());
- step.setData(resource);
-
- if(copyResource(step)) {
- File resourceFile = new File(resource);
- jsonSteps.put(step.toJSON());
- orig.getArgs().set(index, String.format("/f1\"%s\"", resourceFile.getName()));
- log.info("[SUCCESS] Step successfully inferred and appended '{}'", step);
- } else {
- log.error("[SKIPPED] Resources could not be saved '{}'", step);
- }
- }
- }
- }
- }
-}
diff --git a/old code/tray/src/qz/build/provision/Step.java b/old code/tray/src/qz/build/provision/Step.java
deleted file mode 100755
index 59cd65c..0000000
--- a/old code/tray/src/qz/build/provision/Step.java
+++ /dev/null
@@ -1,337 +0,0 @@
-package qz.build.provision;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import qz.build.provision.params.Arch;
-import qz.build.provision.params.Os;
-import qz.build.provision.params.Phase;
-import qz.build.provision.params.Type;
-import qz.build.provision.params.types.Remover;
-import qz.build.provision.params.types.Software;
-
-import java.nio.file.Path;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-
-public class Step {
- protected static final Logger log = LogManager.getLogger(Step.class);
-
- String description;
- Type type;
- List args; // Type.SCRIPT or Type.INSTALLER or Type.CONF only
- HashSet os;
- HashSet arch;
- Phase phase;
- String data;
-
- Path relativePath;
- Class relativeClass;
-
- public Step(Path relativePath, String description, Type type, HashSet os, HashSet arch, Phase phase, String data, List args) {
- this.relativePath = relativePath;
- this.description = description;
- this.type = type;
- this.os = os;
- this.arch = arch;
- this.phase = phase;
- this.data = data;
- this.args = args;
- }
-
- /**
- * Only should be used by unit tests
- */
- Step(Class relativeClass, String description, Type type, HashSet os, HashSet arch, Phase phase, String data, List args) {
- this.relativeClass = relativeClass;
- this.description = description;
- this.type = type;
- this.os = os;
- this.arch = arch;
- this.phase = phase;
- this.data = data;
- this.args = args;
- }
-
- @Override
- public String toString() {
- return "Step { " +
- "description=\"" + description + "\", " +
- "type=\"" + type + "\", " +
- "os=\"" + Os.serialize(os) + "\", " +
- "arch=\"" + Arch.serialize(arch) + "\", " +
- "phase=\"" + phase + "\", " +
- "data=\"" + data + "\", " +
- "args=\"" + StringUtils.join(args, ",") + "\" " +
- "}";
- }
-
- public JSONObject toJSON() throws JSONException {
- JSONObject json = new JSONObject();
- json.put("description", description)
- .put("type", type)
- .put("os", Os.serialize(os))
- .put("arch", Arch.serialize(arch))
- .put("phase", phase)
- .put("data", data);
-
- for(int i = 0; i < args.size(); i++) {
- json.put(String.format("arg%s", i + 1), args.get(i));
- }
- return json;
- }
-
- public String getDescription() {
- return description;
- }
-
- public Type getType() {
- return type;
- }
-
- public void setType(Type type) {
- this.type = type;
- }
-
- public List getArgs() {
- return args;
- }
-
- public void setArgs(List args) {
- this.args = args;
- }
-
- public HashSet getOs() {
- return os;
- }
-
- public void setOs(HashSet os) {
- this.os = os;
- }
-
- public HashSet getArch() {
- return arch;
- }
-
- public void setArch(HashSet arch) {
- this.arch = arch;
- }
-
- public Phase getPhase() {
- return phase;
- }
-
- public void setPhase(Phase phase) {
- this.phase = phase;
- }
-
- public String getData() {
- return data;
- }
-
- public void setData(String data) {
- this.data = data;
- }
-
- public Class getRelativeClass() {
- return relativeClass;
- }
-
- public Path getRelativePath() {
- return relativePath;
- }
-
- public boolean usingClass() {
- return relativeClass != null;
- }
-
- public boolean usingPath() {
- return relativePath != null;
- }
-
- public static Step parse(JSONObject jsonStep, Object relativeObject) {
- String description = jsonStep.optString("description", "");
- Type type = Type.parse(jsonStep.optString("type", null));
- String data = jsonStep.optString("data", null);
-
- // Handle installer args
- List args = new LinkedList<>();
- if(type == Type.SOFTWARE || type == Type.CONF) {
- // Handle space-delimited args
- args = Software.parseArgs(jsonStep.optString("args", ""));
- // Handle standalone single args (won't break on whitespace)
- // e.g. "arg1": "C:\Program Files\Foo"
- int argCounter = 0;
- while(true) {
- String singleArg = jsonStep.optString(String.format("arg%d", ++argCounter), "");
- if(!singleArg.trim().isEmpty()) {
- args.add(singleArg.trim());
- } else {
- // stop searching if the next incremental arg (e.g. "arg2") isn't found
- break;
- }
- }
- }
-
- // Mandate "args" as the CONF path
- if(type == Type.CONF) {
- // Honor "path" first, if provided
- String path = jsonStep.optString("path", "");
- if(!path.isEmpty()) {
- args.add(0, path);
- }
-
- // Keep only the first value
- if(args.size() > 0) {
- args = args.subList(0, 1);
- } else {
- throw formatted("Conf path value cannot be blank.");
- }
- }
-
- HashSet os = new HashSet<>();
- if(jsonStep.has("os")) {
- // Do not tolerate bad os values
- String osString = jsonStep.optString("os");
- os = Os.parse(osString);
- if(os.size() == 0) {
- throw formatted("Os provided '%s' could not be parsed", osString);
- }
- }
-
- HashSet arch = new HashSet<>();
- if(jsonStep.has("arch")) {
- // Do not tolerate bad arch values
- String archString = jsonStep.optString("arch");
- arch = Arch.parse(archString);
- if(arch.size() == 0) {
- throw formatted("Arch provided \"%s\" could not be parsed", archString);
- }
- }
-
- Phase phase = null;
- if(jsonStep.has("phase")) {
- String phaseString = jsonStep.optString("phase", null);
- phase = Phase.parse(phaseString);
- if(phase == null) {
- log.warn("Phase provided \"{}\" could not be parsed", phaseString);
- }
- }
- Step step;
- if(relativeObject instanceof Path) {
- step = new Step((Path)relativeObject, description, type, os, arch, phase, data, args);
- } else if(relativeObject instanceof Class) {
- step = new Step((Class)relativeObject, description, type, os, arch, phase, data, args);
- } else {
- throw formatted("Parameter relativeObject must be of type 'Path' or 'Class' but '%s' was provided", relativeObject.getClass());
- }
- return step.sanitize();
- }
-
- private Step sanitize() {
- return throwIfNull("Type", type)
- .throwIfNull("Data", data)
- .validateOs()
- .validateArch()
- .enforcePhase(Type.PREFERENCE, Phase.STARTUP)
- .enforcePhase(Type.CA, Phase.CERTGEN)
- .enforcePhase(Type.CERT, Phase.STARTUP)
- .enforcePhase(Type.CONF, Phase.CERTGEN)
- .enforcePhase(Type.SOFTWARE, Phase.INSTALL)
- .enforcePhase(Type.REMOVER, Phase.INSTALL)
- .enforcePhase(Type.PROPERTY, Phase.CERTGEN, Phase.INSTALL)
- .validateRemover();
- }
-
- private Step validateRemover() {
- if(type != Type.REMOVER) {
- return this;
- }
- Remover remover = Remover.parse(data);
- switch(remover) {
- case CUSTOM:
- break;
- default:
- if(remover.matchesCurrentSystem()) {
- throw formatted("Remover '%s' would conflict with this installer, skipping. ", remover);
- }
- return this;
- }
-
- // Custom removers must have three elements
- if(data == null || data.split(",").length != 3) {
- throw formatted("Remover data '%s' is invalid. Data must match a known type [%s] or contain exactly 3 elements.", data, Remover.valuesDelimited(","));
- }
- return this;
- }
-
- private Step throwIfNull(String name, Object value) {
- if(value == null) {
- throw formatted("%s cannot be null", name);
- }
- return this;
- }
-
- private Step validateOs() {
- if(os == null) {
- if(type == Type.SOFTWARE) {
- // Software must default to a sane operating system
- os = Software.parse(data).defaultOs();
- } else {
- os = new HashSet<>();
- }
- }
- if(os.size() == 0) {
- os.add(Os.ALL);
- log.debug("Os list is null, assuming '{}'", Os.ALL);
- }
- return this;
- }
-
- private Step validateArch() {
- if(arch == null) {
- arch = new HashSet<>();
- }
- if(arch.size() == 0) {
- arch.add(Arch.ALL);
- log.debug("Arch list is null, assuming '{}'", Arch.ALL);
- }
- return this;
- }
-
- private Step enforcePhase(Type matchType, Phase ... requiredPhases) {
- if(requiredPhases.length == 0) {
- throw new UnsupportedOperationException("At least one Phase must be specified");
- }
- if(type == matchType) {
- for(Phase requiredPhase : requiredPhases) {
- if (phase == null) {
- phase = requiredPhase;
- log.debug("Phase is null, defaulting to '{}' based on Type '{}'", phase, type);
- return this;
- } else if (phase == requiredPhase) {
- return this;
- }
- }
- log.debug("Phase '{}' is unsupported for Type '{}', defaulting to '{}'", phase, type, phase = requiredPhases[0]);
- }
- return this;
- }
-
- private static UnsupportedOperationException formatted(String message, Object ... args) {
- String formatted = String.format(message, args);
- return new UnsupportedOperationException(formatted);
- }
- Step cloneTo(Phase phase) {
- return relativePath != null ?
- new Step(relativePath, description, type, os, arch, phase, data, args) :
- new Step(relativeClass, description, type, os, arch, phase, data, args);
- }
-
- public Step clone() {
- return cloneTo(this.phase);
- }
-}
diff --git a/old code/tray/src/qz/build/provision/params/Arch.java b/old code/tray/src/qz/build/provision/params/Arch.java
deleted file mode 100755
index 4f8e662..0000000
--- a/old code/tray/src/qz/build/provision/params/Arch.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package qz.build.provision.params;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Locale;
-
-/**
- * Basic architecture parser
- *
- * Note: All aliases must be lowercase
- */
-public enum Arch {
- X86("x32", "i386", "i486", "i586", "i686"),
- X86_64("amd64"),
- ARM32("arm", "armv1", "armv2", "armv3", "armv4", "armv5", "armv6", "armv7"),
- AARCH64("arm64", "armv8", "armv9"),
- RISCV32("rv32"),
- RISCV64("rv64"),
- PPC64("powerpc", "powerpc64"),
- ALL(), // special handling
- UNKNOWN();
-
- private HashSet aliases = new HashSet<>();
- Arch(String ... aliases) {
- this.aliases.add(name().toLowerCase(Locale.ENGLISH));
- this.aliases.addAll(Arrays.asList(aliases));
- }
-
- public static Arch parseStrict(String input) throws UnsupportedOperationException {
- return EnumParser.parseStrict(Arch.class, input, ALL, UNKNOWN);
- }
-
- public static HashSet parse(String input) {
- return EnumParser.parseSet(Arch.class, Arch.ALL, input);
- }
-
- public static Arch parse(String input, Arch fallback) {
- Arch found = bestMatch(input);
- return found == UNKNOWN ? fallback : found;
- }
-
- public static Arch bestMatch(String input) {
- if(input != null) {
- for(Arch arch : values()) {
- if (arch.aliases.contains(input.toLowerCase())) {
- return arch;
- }
- }
- }
- return Arch.UNKNOWN;
- }
-
- public boolean matches(HashSet archList) {
- return this == ALL || archList.contains(ALL) || (this != UNKNOWN && archList.contains(this));
- }
-
- public static String serialize(HashSet archList) {
- if(archList.contains(ALL)) {
- return "*";
- }
- return StringUtils.join(archList, "|");
- }
-
- @Override
- public String toString() {
- return super.toString().toLowerCase(Locale.ENGLISH);
- }
-}
diff --git a/old code/tray/src/qz/build/provision/params/EnumParser.java b/old code/tray/src/qz/build/provision/params/EnumParser.java
deleted file mode 100755
index 5a9dd33..0000000
--- a/old code/tray/src/qz/build/provision/params/EnumParser.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package qz.build.provision.params;
-
-import java.util.EnumSet;
-import java.util.HashSet;
-
-public interface EnumParser {
- /**
- * Basic enum parser
- */
-
- static > T parse(Class clazz, String s) {
- return parse(clazz, s, null);
- }
-
- static > T parse(Class clazz, String s, T fallbackValue) {
- if(s != null) {
- for(T en : EnumSet.allOf(clazz)) {
- if (en.name().equalsIgnoreCase(s)) {
- return en;
- }
- }
- }
- return fallbackValue;
- }
-
- static > T parseStrict(Class clazz, String s, T ... blocklist) throws UnsupportedOperationException {
- if(s != null) {
- HashSet matched = parseSet(clazz, null, s);
- if (matched.size() == 1) {
- T returnVal = matched.iterator().next();
- boolean blocked = false;
- for(T block : blocklist) {
- if(returnVal == block) {
- blocked = true;
- break;
- }
- }
- if(!blocked) {
- return returnVal;
- }
- }
- }
- throw new UnsupportedOperationException(String.format("%s value '%s' failed to match one and only one item", clazz.getSimpleName(), s));
- }
-
- static > HashSet parseSet(Class clazz, T all, String s) {
- HashSet matched = new HashSet<>();
- if(s != null) {
- // Handle ALL="*"
- if (all != null && s.equals("*")) {
- matched.add(all);
- }
-
- String[] parts = s.split("\\|");
- for(String part : parts) {
- T parsed = parse(clazz, part);
- if (parsed != null) {
- matched.add(parsed);
- }
- }
- }
- return matched;
- }
-}
diff --git a/old code/tray/src/qz/build/provision/params/Os.java b/old code/tray/src/qz/build/provision/params/Os.java
deleted file mode 100755
index 7785912..0000000
--- a/old code/tray/src/qz/build/provision/params/Os.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package qz.build.provision.params;
-
-import org.apache.commons.lang3.StringUtils;
-import qz.utils.SystemUtilities;
-
-import java.util.*;
-
-/**
- * Basic OS parser
- */
-public enum Os {
- WINDOWS,
- MAC,
- LINUX,
- SOLARIS, // unsupported
- ALL, // special handling
- UNKNOWN;
-
- public boolean matches(HashSet osList) {
- return this == ALL || osList.contains(ALL) || (this != UNKNOWN && osList.contains(this));
- }
-
- public static boolean matchesHost(HashSet osList) {
- for(Os os : osList) {
- if(os == SystemUtilities.getOs() || os == ALL) {
- return true;
- }
- }
- return false;
- }
-
- public static Os parseStrict(String input) throws UnsupportedOperationException {
- return EnumParser.parseStrict(Os.class, input, ALL, UNKNOWN);
- }
-
- public static Os bestMatch(String input) {
- if(input != null) {
- String name = input.toLowerCase(Locale.ENGLISH);
- if (name.contains("win")) {
- return Os.WINDOWS;
- } else if (name.contains("mac")) {
- return Os.MAC;
- } else if (name.contains("linux")) {
- return Os.LINUX;
- } else if (name.contains("sunos")) {
- return Os.SOLARIS;
- }
- }
- return Os.UNKNOWN;
- }
-
- public static HashSet parse(String input) {
- return EnumParser.parseSet(Os.class, Os.ALL, input);
- }
-
- public static String serialize(HashSet osList) {
- if(osList.contains(ALL)) {
- return "*";
- }
- return StringUtils.join(osList, "|");
- }
-
- @Override
- public String toString() {
- return super.toString().toLowerCase(Locale.ENGLISH);
- }
-}
\ No newline at end of file
diff --git a/old code/tray/src/qz/build/provision/params/Phase.java b/old code/tray/src/qz/build/provision/params/Phase.java
deleted file mode 100755
index 382f119..0000000
--- a/old code/tray/src/qz/build/provision/params/Phase.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package qz.build.provision.params;
-
-import java.util.Locale;
-
-public enum Phase {
- INSTALL,
- CERTGEN,
- STARTUP,
- UNINSTALL;
-
- public static Phase parse(String input) {
- return EnumParser.parse(Phase.class, input);
- }
-
- @Override
- public String toString() {
- return super.toString().toLowerCase(Locale.ENGLISH);
- }
-}
diff --git a/old code/tray/src/qz/build/provision/params/Type.java b/old code/tray/src/qz/build/provision/params/Type.java
deleted file mode 100755
index cda4e8a..0000000
--- a/old code/tray/src/qz/build/provision/params/Type.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package qz.build.provision.params;
-
-import java.util.Locale;
-
-public enum Type {
- SCRIPT,
- SOFTWARE,
- RESOURCE,
- REMOVER, // QZ Tray remover
- CA,
- CERT,
- CONF,
- PROPERTY,
- PREFERENCE;
-
- public static Type parse(String input) {
- return EnumParser.parse(Type.class, input);
- }
-
- @Override
- public String toString() {
- return super.toString().toLowerCase(Locale.ENGLISH);
- }
-}
diff --git a/old code/tray/src/qz/build/provision/params/types/Remover.java b/old code/tray/src/qz/build/provision/params/types/Remover.java
deleted file mode 100755
index 7b8b635..0000000
--- a/old code/tray/src/qz/build/provision/params/types/Remover.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package qz.build.provision.params.types;
-
-import org.apache.commons.lang3.StringUtils;
-import qz.build.provision.params.EnumParser;
-import qz.common.Constants;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Locale;
-
-public enum Remover {
- QZ("QZ Tray", "qz-tray", "qz"),
- CUSTOM(null, null, null); // reserved
-
- private String aboutTitle;
- private String propsFile;
- private String dataDir;
-
- Remover(String aboutTitle, String propsFile, String dataDir) {
- this.aboutTitle = aboutTitle;
- this.propsFile = propsFile;
- this.dataDir = dataDir;
- }
-
- public String getAboutTitle() {
- return aboutTitle;
- }
-
- public String getPropsFile() {
- return propsFile;
- }
-
- public String getDataDir() {
- return dataDir;
- }
-
- public static String valuesDelimited(String delimiter) {
- ArrayList listing = new ArrayList<>(Arrays.asList(values()));
- listing.remove(CUSTOM);
- return StringUtils.join(listing, delimiter).toLowerCase(Locale.ENGLISH);
- }
-
- /**
- * Defaults to custom if not found
- */
- public static Remover parse(String input) {
- Remover remover = EnumParser.parse(Remover.class, input);
- if(remover == CUSTOM) {
- throw new UnsupportedOperationException("Remover 'custom' is reserved for internal purposes");
- }
- if(remover == null) {
- remover = CUSTOM;
- }
- return remover;
- }
-
- public boolean matchesCurrentSystem() {
- return Constants.ABOUT_TITLE.equals(aboutTitle) ||
- Constants.PROPS_FILE.equals(propsFile) ||
- Constants.DATA_DIR.equals(dataDir);
- }
-
- @Override
- public String toString() {
- return super.toString().toLowerCase(Locale.ENGLISH);
- }
-}
diff --git a/old code/tray/src/qz/build/provision/params/types/Script.java b/old code/tray/src/qz/build/provision/params/types/Script.java
deleted file mode 100755
index 1d480bb..0000000
--- a/old code/tray/src/qz/build/provision/params/types/Script.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package qz.build.provision.params.types;
-
-import org.apache.commons.io.FilenameUtils;
-import qz.build.provision.params.EnumParser;
-
-import java.nio.file.Path;
-import java.util.Locale;
-
-public enum Script {
- PS1,
- BAT,
- SH,
- PY,
- RB;
-
- public static Script parse(String input) {
- if(input != null && !input.isEmpty()) {
- return EnumParser.parse(Script.class, FilenameUtils.getExtension(input), SH);
- }
- return null;
- }
-
- public static Script parse(Path path) {
- return parse(path.toAbsolutePath().toString());
- }
-
- @Override
- public String toString() {
- return super.toString().toLowerCase(Locale.ENGLISH);
- }
-}
\ No newline at end of file
diff --git a/old code/tray/src/qz/build/provision/params/types/Software.java b/old code/tray/src/qz/build/provision/params/types/Software.java
deleted file mode 100755
index aee64c6..0000000
--- a/old code/tray/src/qz/build/provision/params/types/Software.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package qz.build.provision.params.types;
-
-import org.apache.commons.io.FilenameUtils;
-import qz.build.provision.params.EnumParser;
-import qz.build.provision.params.Os;
-
-import java.nio.file.Path;
-import java.util.*;
-
-public enum Software {
- EXE,
- MSI,
- PKG,
- DMG,
- RUN,
- UNKNOWN;
-
- public static Software parse(String input) {
- return EnumParser.parse(Software.class, FilenameUtils.getExtension(input), UNKNOWN);
- }
-
- public static Software parse(Path path) {
- return parse(path.toString());
- }
-
- public static List parseArgs(String input) {
- List args = new LinkedList<>();
- if(input != null) {
- String[] parts = input.split(" ");
- for(String part : parts) {
- if(!part.trim().isEmpty()) {
- args.add(part.trim());
- }
- }
- }
- return args;
- }
-
- public HashSet defaultOs() {
- HashSet list = new HashSet<>();
- switch(this) {
- case EXE:
- case MSI:
- list.add(Os.WINDOWS);
- break;
- case PKG:
- case DMG:
- list.add(Os.MAC);
- break;
- case RUN:
- list.add(Os.LINUX);
- break;
- default:
- list.add(Os.ALL);
- }
- return list;
- }
-
- @Override
- public String toString() {
- return super.toString().toLowerCase(Locale.ENGLISH);
- }
-}
diff --git a/old code/tray/src/qz/common/AboutInfo.java b/old code/tray/src/qz/common/AboutInfo.java
deleted file mode 100755
index 87d06c4..0000000
--- a/old code/tray/src/qz/common/AboutInfo.java
+++ /dev/null
@@ -1,205 +0,0 @@
-package qz.common;
-
-import com.github.zafarkhaja.semver.Version;
-import org.apache.commons.lang3.time.DurationFormatUtils;
-import org.apache.commons.ssl.Base64;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.x509.extension.X509ExtensionUtil;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import qz.installer.certificate.KeyPairWrapper;
-import qz.installer.certificate.CertificateManager;
-import qz.utils.MacUtilities;
-import qz.utils.StringUtilities;
-import qz.utils.SystemUtilities;
-import qz.ws.PrintSocketServer;
-import qz.ws.WebsocketPorts;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.*;
-
-public class AboutInfo {
-
- private static final Logger log = LogManager.getLogger(AboutInfo.class);
-
- private static String preferredHostname = "localhost";
-
- public static JSONObject gatherAbout(String domain, CertificateManager certificateManager) {
- JSONObject about = new JSONObject();
-
- try {
- about.put("product", product());
- about.put("socket", socket(certificateManager, domain));
- about.put("environment", environment());
- about.put("ssl", ssl(certificateManager));
- about.put("libraries", libraries());
- about.put("charsets", charsets());
- }
- catch(JSONException | GeneralSecurityException e) {
- log.error("Failed to write JSON data", e);
- }
-
- return about;
- }
-
- private static JSONObject product() throws JSONException {
- JSONObject product = new JSONObject();
-
- product
- .put("title", Constants.ABOUT_TITLE)
- .put("version", Constants.VERSION)
- .put("vendor", Constants.ABOUT_COMPANY)
- .put("url", Constants.ABOUT_URL);
-
- return product;
- }
-
- private static JSONObject socket(CertificateManager certificateManager, String domain) throws JSONException {
- JSONObject socket = new JSONObject();
- String sanitizeDomain = StringUtilities.escapeHtmlEntities(domain);
- WebsocketPorts websocketPorts = PrintSocketServer.getWebsocketPorts();
-
- // Gracefully handle XSS per https://github.com/qzind/tray/issues/1099
- if(sanitizeDomain.contains("<") || sanitizeDomain.contains(">")) {
- log.warn("Something smells fishy about this domain: \"{}\", skipping", domain);
- sanitizeDomain = "unknown";
- }
-
- socket
- .put("domain", sanitizeDomain)
- .put("secureProtocol", "wss")
- .put("securePort", certificateManager.isSslActive() ? websocketPorts.getSecurePort() : "none")
- .put("insecureProtocol", "ws")
- .put("insecurePort", websocketPorts.getInsecurePort());
-
- return socket;
- }
-
- private static JSONObject environment() throws JSONException {
- JSONObject environment = new JSONObject();
-
- long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
-
- environment
- .put("os", SystemUtilities.getOsDisplayName())
- .put("os version", SystemUtilities.getOsDisplayVersion())
- .put("java", String.format("%s (%s)", Constants.JAVA_VERSION, SystemUtilities.getArch().toString().toLowerCase()))
- .put("java (location)", System.getProperty("java.home"))
- .put("java (vendor)", Constants.JAVA_VENDOR)
- .put("uptime", DurationFormatUtils.formatDurationWords(uptime, true, false))
- .put("uptimeMillis", uptime)
- .put("sandbox", SystemUtilities.isMac() && MacUtilities.isSandboxed());
-
- return environment;
- }
-
- private static JSONObject ssl(CertificateManager certificateManager) throws JSONException, CertificateEncodingException {
- JSONObject ssl = new JSONObject();
-
- JSONArray certs = new JSONArray();
-
- for (KeyPairWrapper keyPair : new KeyPairWrapper[]{certificateManager.getCaKeyPair(), certificateManager.getSslKeyPair() }) {
- X509Certificate x509 = keyPair.getCert();
- if (x509 != null) {
- JSONObject cert = new JSONObject();
- cert.put("alias", keyPair.getAlias());
- try {
- ASN1Primitive ext = X509ExtensionUtil.fromExtensionValue(x509.getExtensionValue(Extension.basicConstraints.getId()));
- cert.put("rootca", BasicConstraints.getInstance(ext).isCA());
- }
- catch(IOException | NullPointerException e) {
- cert.put("rootca", false);
- }
- cert.put("subject", x509.getSubjectX500Principal().getName());
- cert.put("expires", SystemUtilities.toISO(x509.getNotAfter()));
- cert.put("data", formatCert(x509.getEncoded()));
- certs.put(cert);
- }
- }
- ssl.put("certificates", certs);
-
- return ssl;
- }
-
- public static String formatCert(byte[] encoding) {
- return "-----BEGIN CERTIFICATE-----\r\n" +
- new String(Base64.encodeBase64(encoding, true), StandardCharsets.UTF_8) +
- "-----END CERTIFICATE-----\r\n";
- }
-
- private static JSONObject libraries() throws JSONException {
- JSONObject libraries = new JSONObject();
-
- SortedMap libs = SecurityInfo.getLibVersions();
- for(Map.Entry entry : libs.entrySet()) {
- String version = entry.getValue();
- if (version == null) { version = "unknown"; }
-
- libraries.put(entry.getKey(), version);
- }
-
- return libraries;
- }
-
- private static JSONObject charsets() throws JSONException {
- JSONObject charsets = new JSONObject();
-
- SortedMap avail = Charset.availableCharsets();
- ArrayList names = new ArrayList<>();
- for(Map.Entry entry : avail.entrySet()) {
- names.add(entry.getValue().name());
- }
-
- charsets.put("charsets", Arrays.toString(names.toArray()));
- return charsets;
- }
-
- public static String getPreferredHostname() {
- return preferredHostname;
- }
-
- public static Version findLatestVersion() {
- log.trace("Looking for newer versions of {} online", Constants.ABOUT_TITLE);
- try {
- URL api = new URL(Constants.VERSION_CHECK_URL);
- BufferedReader br = new BufferedReader(new InputStreamReader(api.openStream()));
-
- StringBuilder rawJson = new StringBuilder();
- String line;
- while((line = br.readLine()) != null) {
- rawJson.append(line);
- }
-
- JSONArray versions = new JSONArray(rawJson.toString());
- for(int i = 0; i < versions.length(); i++) {
- JSONObject versionData = versions.getJSONObject(i);
- if(versionData.getString("target_commitish").equals("master")) {
- Version latestVersion = Version.valueOf(versionData.getString("name"));
- log.trace("Found latest version of {} online: {}", Constants.ABOUT_TITLE, latestVersion);
- return latestVersion;
- }
- }
- throw new Exception("Could not find valid json version information online.");
- }
- catch(Exception e) {
- log.error("Failed to get latest version of {} online", Constants.ABOUT_TITLE, e);
- }
-
- return Constants.VERSION;
- }
-
-}
diff --git a/old code/tray/src/qz/common/ByteArrayBuilder.java b/old code/tray/src/qz/common/ByteArrayBuilder.java
deleted file mode 100755
index dc66bd4..0000000
--- a/old code/tray/src/qz/common/ByteArrayBuilder.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/**
- * @author Antoni Ten Monro's
- *
- * Copyright (C) 2016 Tres Finocchiaro, QZ Industries, LLC
- * Copyright (C) 2013 Antoni Ten Monro's
- *
- * LGPL 2.1 This is free software. This software and source code are released under
- * the "LGPL 2.1 License". A copy of this license should be distributed with
- * this software. http://www.gnu.org/licenses/lgpl-2.1.html
- *
- */
-
-package qz.common;
-
-import org.apache.commons.lang3.ArrayUtils;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides a simple and efficient way for concatenating byte arrays, similar
- * in purpose to StringBuilder. Objects of this class are not
- * thread safe and include no synchronization
- *
- * @author Antoni Ten Monro's
- */
-@SuppressWarnings("UnusedDeclaration") //Library class
-public final class ByteArrayBuilder {
-
- private List buffer;
-
-
- /**
- * Creates a new ByteArrayBuilder and sets initial capacity to 10
- */
- public ByteArrayBuilder() {
- this(null);
- }
-
- /**
- * Creates a new ByteArrayBuilder and sets initial capacity to
- * initialCapacity
- *
- * @param initialCapacity the initial capacity of the ByteArrayBuilder
- */
- public ByteArrayBuilder(int initialCapacity) {
- this(null, initialCapacity);
- }
-
- /**
- * Creates a new ByteArrayBuilder, sets initial capacity to 10
- * and appends initialContents
- *
- * @param initialContents the initial contents of the ByteArrayBuilder
- */
- public ByteArrayBuilder(byte[] initialContents) {
- this(initialContents, 16);
- }
-
- /**
- * Creates a new ByteArrayBuilder, sets initial capacity to
- * initialContents and appends initialContents
- *
- * @param initialContents the initial contents of the ByteArrayBuilder
- * @param initialCapacity the initial capacity of the ByteArrayBuilder
- */
- public ByteArrayBuilder(byte[] initialContents, int initialCapacity) {
- buffer = new ArrayList<>(initialCapacity);
- if (initialContents != null) {
- append(initialContents);
- }
- }
-
- /**
- * Empties the ByteArrayBuilder
- */
- public void clear() {
- buffer.clear();
- }
-
- /**
- * Clear a portion of the ByteArrayBuilder
- *
- * @param startIndex Starting index, inclusive
- * @param endIndex Ending index, exclusive
- */
- public final void clearRange(int startIndex, int endIndex) {
- buffer.subList(startIndex, endIndex).clear();
- }
-
- /**
- * Gives the number of bytes currently stored in this ByteArrayBuilder
- *
- * @return the number of bytes in the ByteArrayBuilder
- */
- public int getLength() {
- return buffer.size();
- }
-
- /**
- * Appends a new byte array to this ByteArrayBuilder.
- * Returns this same object to allow chaining calls
- *
- * @param bytes the byte array to append
- * @return this ByteArrayBuilder
- */
- public final ByteArrayBuilder append(byte[] bytes) {
- for(byte b : bytes) {
- buffer.add(b);
- }
- return this;
- }
-
- public final ByteArrayBuilder append(List bytes) {
- for(byte b : bytes) {
- buffer.add(b);
- }
- return this;
- }
-
- /**
- * Convenience method for append(byte[]) combined with a StringBuffer of specified
- * charset
- *
- * @param string the String to append
- * @param charset the Charset of the String
- * @return this ByteArrayBuilder
- */
- public final ByteArrayBuilder append(String string, Charset charset) throws UnsupportedEncodingException {
- return append(string.getBytes(charset.name()));
- }
-
- /**
- * Convenience method for append(byte[]) combined with a String of specified
- * charset
- *
- * @param stringBuilder the StringBuilder to append
- * @param charset the Charset of the StringBuilder
- * @return this ByteArrayBuilder
- */
- public final ByteArrayBuilder append(StringBuilder stringBuilder, Charset charset) throws UnsupportedEncodingException {
- return append(stringBuilder.toString(), charset);
- }
-
- /**
- * Returns the full contents of this ByteArrayBuilder as
- * a single byte array.
- *
- * @return The contents of this ByteArrayBuilder as a single byte array
- */
- public byte[] getByteArray() {
- return ArrayUtils.toPrimitive(buffer.toArray(new Byte[buffer.size()]));
- }
-}
diff --git a/old code/tray/src/qz/common/CachedObject.java b/old code/tray/src/qz/common/CachedObject.java
deleted file mode 100755
index 8493d7a..0000000
--- a/old code/tray/src/qz/common/CachedObject.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package qz.common;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Supplier;
-
-/**
- * A generic class that encapsulates an object for caching. The cached object
- * will be refreshed automatically when accessed after its lifespan has expired.
- *
- * @param The type of object to be cached.
- */
-public class CachedObject {
- public static final long DEFAULT_LIFESPAN = 5000; // in milliseconds
- T lastObject;
- Supplier supplier;
- private long timestamp;
- private long lifespan;
-
- /**
- * Creates a new CachedObject with a default lifespan of 5000 milliseconds
- *
- * @param supplier The function to pull new values from
- */
- public CachedObject(Supplier supplier) {
- this(supplier, DEFAULT_LIFESPAN);
- }
-
- /**
- * Creates a new CachedObject
- *
- * @param supplier The function to pull new values from
- * @param lifespan The lifespan of the cached object in milliseconds
- */
- public CachedObject(Supplier supplier, long lifespan) {
- this.supplier = supplier;
- setLifespan(lifespan);
- timestamp = Long.MIN_VALUE; // System.nanoTime() can be negative, MIN_VALUE guarantees a first-run.
- }
-
- /**
- * Registers a new supplier for the CachedObject
- *
- * @param supplier The function to pull new values from
- */
- @SuppressWarnings("unused")
- public void registerSupplier(Supplier supplier) {
- this.supplier = supplier;
- }
-
- /**
- * Sets the lifespan of the cached object
- *
- * @param milliseconds The lifespan of the cached object in milliseconds
- */
- public void setLifespan(long milliseconds) {
- lifespan = Math.max(0, milliseconds); // prevent overflow
- }
-
- /**
- * Retrieves the cached object.
- * If the cached object's lifespan has expired, it gets refreshed before being returned.
- *
- * @return The cached object
- */
- public T get() {
- return get(false);
- }
-
- /**
- * Retrieves the cached object.
- * If the cached object's lifespan is expired or forceRefresh is true, it gets refreshed before being returned.
- *
- * @param forceRefresh If true, the cached object will be refreshed before being returned regardless of its lifespan
- * @return The cached object
- */
- public T get(boolean forceRefresh) {
- long now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
- // check lifespan
- if (forceRefresh || (timestamp + lifespan <= now)) {
- timestamp = now;
- lastObject = supplier.get();
- }
- return lastObject;
- }
-
- // Test
- public static void main(String ... args) throws InterruptedException {
- final AtomicInteger testInt = new AtomicInteger(0);
-
- CachedObject cachedString = new CachedObject<>(testInt::incrementAndGet);
- for(int i = 0; i < 100; i++) {
- Thread.sleep(1500);
- System.out.println(cachedString.get());
- }
- }
-}
diff --git a/old code/tray/src/qz/common/Constants.java b/old code/tray/src/qz/common/Constants.java
deleted file mode 100755
index c883085..0000000
--- a/old code/tray/src/qz/common/Constants.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package qz.common;
-
-import com.github.zafarkhaja.semver.Version;
-import qz.utils.SystemUtilities;
-
-import java.awt.*;
-
-import static qz.ws.SingleInstanceChecker.STEAL_WEBSOCKET_PROPERTY;
-
-/**
- * Created by robert on 7/9/2014.
- */
-public class Constants {
- public static final String HEXES = "0123456789ABCDEF";
- public static final char[] HEXES_ARRAY = HEXES.toCharArray();
- public static final int BYTE_BUFFER_SIZE = 8192;
- public static final Version VERSION = Version.valueOf("2.2.6-SNAPSHOT");
- public static final Version JAVA_VERSION = SystemUtilities.getJavaVersion();
- public static final String JAVA_VENDOR = System.getProperty("java.vendor");
-
- /* QZ-Tray Constants */
- public static final String BLOCK_FILE = "blocked";
- public static final String ALLOW_FILE = "allowed";
- public static final String TEMP_FILE = "temp";
- public static final String LOG_FILE = "debug";
- public static final String PROPS_FILE = "qz-tray"; // .properties extension is assumed
- public static final String PREFS_FILE = "prefs"; // .properties extension is assumed
- public static final String[] PERSIST_PROPS = {"file.whitelist", "file.allow", "networking.hostname", "networking.port", STEAL_WEBSOCKET_PROPERTY };
- public static final String AUTOSTART_FILE = ".autostart";
- public static final String DATA_DIR = "qz";
-
- public static final int BORDER_PADDING = 10;
-
- public static final String ABOUT_TITLE = "QZ Tray";
- public static final String ABOUT_EMAIL = "support@qz.io";
- public static final String ABOUT_URL = "https://qz.io";
- public static final String ABOUT_COMPANY = "QZ Industries, LLC";
- public static final String ABOUT_CITY = "Canastota";
- public static final String ABOUT_STATE = "NY";
- public static final String ABOUT_COUNTRY = "US";
-
- public static final String ABOUT_LICENSING_URL = Constants.ABOUT_URL + "/licensing";
- public static final String ABOUT_SUPPORT_URL = Constants.ABOUT_URL + "/support";
- public static final String ABOUT_PRIVACY_URL = Constants.ABOUT_URL + "/privacy";
- public static final String ABOUT_DOWNLOAD_URL = Constants.ABOUT_URL + "/download";
-
- public static final String VERSION_CHECK_URL = "https://api.github.com/repos/qzind/tray/releases";
- public static final String VERSION_DOWNLOAD_URL = "https://github.com/qzind/tray/releases";
- public static final boolean ENABLE_DIAGNOSTICS = true; // Diagnostics menu (logs, etc)
-
- public static final String TRUSTED_CERT = String.format("Verified by %s", Constants.ABOUT_COMPANY);
- public static final String SPONSORED_CERT = String.format("Sponsored by %s", Constants.ABOUT_COMPANY);
- public static final String SPONSORED_TOOLTIP = "Sponsored organization";
- public static final String UNTRUSTED_CERT = "Untrusted website";
- public static final String NO_TRUST = "Cannot verify trust";
-
- public static final String PROBE_REQUEST = "getProgramName";
- public static final String PROBE_RESPONSE = ABOUT_TITLE;
-
- public static final String ALLOW_SITES_TEXT = "Permanently allowed \"%s\" to access local resources";
- public static final String BLOCK_SITES_TEXT = "Permanently blocked \"%s\" from accessing local resources";
-
- public static final String REMEMBER_THIS_DECISION = "Remember this decision";
- public static final String STRICT_MODE_LABEL = "Use strict certificate mode";
- public static final String STRICT_MODE_TOOLTIP = String.format("Prevents the ability to select \"%s\" for most websites", REMEMBER_THIS_DECISION);
- public static final String STRICT_MODE_CONFIRM = String.format("Set strict certificate mode? Most websites will stop working with %s.", ABOUT_TITLE);
- public static final String ALLOW_SITES_LABEL = "Sites permanently allowed access";
- public static final String BLOCK_SITES_LABEL = "Sites permanently blocked from access";
-
-
- public static final String ALLOWED = "Allowed";
- public static final String BLOCKED = "Blocked";
-
- public static final String OVERRIDE_CERT = "override.crt";
- public static final String WHITELIST_CERT_DIR = "whitelist";
- public static final String PROVISION_DIR = "provision";
- public static final String PROVISION_FILE = "provision.json";
-
- public static final String SIGNING_PRIVATE_KEY = "private-key.pem";
- public static final String SIGNING_CERTIFICATE = "digital-certificate.txt";
-
- public static final long VALID_SIGNING_PERIOD = 15 * 60 * 1000; //millis
- public static final int EXPIRY_WARN = 30; // days
- public static final Color WARNING_COLOR_LITE = Color.RED;
- public static final Color TRUSTED_COLOR_LITE = Color.BLUE;
- public static final Color WARNING_COLOR_DARK = Color.decode("#EB6261");
- public static final Color TRUSTED_COLOR_DARK = Color.decode("#589DF6");
- public static Color WARNING_COLOR = WARNING_COLOR_LITE;
- public static Color TRUSTED_COLOR = TRUSTED_COLOR_LITE;
-
- public static boolean MASK_TRAY_SUPPORTED = true;
-
- public static final long MEMORY_PER_PRINT = 512; //MB
-
- public static final String RAW_PRINT = ABOUT_TITLE + " Raw Print";
- public static final String IMAGE_PRINT = ABOUT_TITLE + " Pixel Print";
- public static final String PDF_PRINT = ABOUT_TITLE + " PDF Print";
- public static final String HTML_PRINT = ABOUT_TITLE + " HTML Print";
-
- public static final Integer[] DEFAULT_WSS_PORTS = {8181, 8282, 8383, 8484};
- public static final Integer[] DEFAULT_WS_PORTS = {8182, 8283, 8384, 8485};
- public static final Integer[] CUPS_RSS_PORTS = {8586, 8687, 8788, 8889};
-}
diff --git a/old code/tray/src/qz/common/PropertyHelper.java b/old code/tray/src/qz/common/PropertyHelper.java
deleted file mode 100755
index 7ba83e3..0000000
--- a/old code/tray/src/qz/common/PropertyHelper.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package qz.common;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import qz.utils.ArgValue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-/**
- * Created by Tres on 12/16/2015.
- */
-public class PropertyHelper extends Properties {
- private static final Logger log = LogManager.getLogger(PropertyHelper.class);
- private String file;
-
- /**
- * Default constructor
- */
- public PropertyHelper() {
- super();
- }
-
- /**
- * Default constructor
- * @param p Initial Properties
- */
- public PropertyHelper(Properties p) {
- super(p);
- }
-
- /**
- * Custom constructor, attempts to load from file
- * @param file File to load properties from
- */
- public PropertyHelper(String file) {
- super();
- this.file = file;
- load(file);
- }
-
- public PropertyHelper(File file) {
- this(file == null ? null : file.getAbsolutePath());
- }
-
- public boolean getBoolean(String key, boolean defaultVal) {
- String prop = getProperty(key);
- if (prop != null) {
- return Boolean.parseBoolean(prop);
- } else {
- return defaultVal;
- }
- }
-
- public void setProperty(ArgValue arg, boolean value) {
- setProperty(arg.getMatch(), "" + value);
- }
-
- public void load(File file) {
- load(file == null ? null : file.getAbsolutePath());
- }
-
- public void load(String file) {
- FileInputStream f = null;
- try {
- f = new FileInputStream(file);
- load(f);
- } catch (IOException e) {
- log.warn("Could not load file: {}, reason: {}", file, e.getLocalizedMessage());
- } finally {
- if (f != null) {
- try { f.close(); } catch(Throwable ignore) {};
- }
- }
- }
-
- public boolean save() {
- boolean success = false;
- FileOutputStream f = null;
- try {
- f = new FileOutputStream(file);
- this.store(f, null);
- success = true;
- } catch (IOException e) {
- log.error("Error saving file: {}", file, e);
- } finally {
- if (f != null) {
- try { f.close(); } catch(Throwable ignore) {};
- }
- }
- return success;
- }
-
- public synchronized Object setProperty(Map.Entry pair) {
- return super.setProperty(pair.getKey(), pair.getValue());
- }
-}
diff --git a/old code/tray/src/qz/common/SecurityInfo.java b/old code/tray/src/qz/common/SecurityInfo.java
deleted file mode 100755
index 4533f53..0000000
--- a/old code/tray/src/qz/common/SecurityInfo.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package qz.common;
-
-import com.sun.jna.Native;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.eclipse.jetty.util.Jetty;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.usb4java.LibUsb;
-import purejavahidapi.PureJavaHidApi;
-import qz.utils.SystemUtilities;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.util.*;
-
-/**
- * Created by Kyle B. on 10/27/2017.
- */
-public class SecurityInfo {
- /**
- * Wrap throwable operations into a try/catch
- */
- private static class CheckedTreeMap extends TreeMap {
- private static final Logger log = LogManager.getLogger(CheckedTreeMap.class);
-
- interface CheckedValue {
- Object check() throws Throwable;
- }
-
- @SuppressWarnings("unchecked")
- public V put(K key, CheckedValue value) {
- try {
- return put(key, (V)value.check());
- } catch(Throwable t) {
- log.warn("A checked exception was suppressed adding key \"{}\"", key, t);
- return put(key, (V)"missing");
- }
- }
- }
-
- private static final Logger log = LogManager.getLogger(SecurityInfo.class);
-
- public static KeyStore getKeyStore(Properties props) {
- if (props != null) {
- String store = props.getProperty("wss.keystore", "");
- char[] pass = props.getProperty("wss.storepass", "").toCharArray();
-
- try {
- KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
- keystore.load(new FileInputStream(store), pass);
- return keystore;
- }
- catch(GeneralSecurityException | IOException e) {
- log.warn("Unable to create keystore from properties file: {}", e.getMessage());
- }
- }
-
- return null;
- }
-
- public static SortedMap getLibVersions() {
- CheckedTreeMap libVersions = new CheckedTreeMap<>();
-
- // Use API-provided mechanism if available
- libVersions.put("jna (native)", () -> Native.VERSION_NATIVE);
- libVersions.put("jna (location)", () -> {
- @SuppressWarnings("unused")
- int ignore = Native.BOOL_SIZE;
- return System.getProperty("jnidispatch.path");
- });
- libVersions.put("jna", Native.VERSION);
- libVersions.put("jssc", () -> jssc.SerialNativeInterface.getLibraryVersion());
- libVersions.put("jssc (native)", () -> jssc.SerialNativeInterface.getNativeLibraryVersion());
- libVersions.put("jetty", Jetty.VERSION);
- libVersions.put("pdfbox", org.apache.pdfbox.util.Version.getVersion());
- libVersions.put("purejavahidapi", () -> PureJavaHidApi.getVersion());
- libVersions.put("usb-api", javax.usb.Version.getApiVersion());
- libVersions.put("not-yet-commons-ssl", org.apache.commons.ssl.Version.VERSION);
- libVersions.put("mslinks", mslinks.ShellLink.VERSION);
- libVersions.put("bouncycastle", "" + new BouncyCastleProvider().getVersion());
- libVersions.put("usb4java (native)", () -> LibUsb.getVersion().toString());
-
- libVersions.put("jre", Constants.JAVA_VERSION.toString());
- libVersions.put("jre (vendor)", Constants.JAVA_VENDOR);
-
- //JFX info, if it exists
- try {
- // "DO NOT LINK JAVAFX EVER" - JavaFX may not exist, use reflection to avoid compilation errors
- Class> VersionInfo = Class.forName("com.sun.javafx.runtime.VersionInfo");
- Path fxPath = Paths.get(VersionInfo.getProtectionDomain().getCodeSource().getLocation().toURI());
- Method method = VersionInfo.getMethod("getVersion");
- Object version = method.invoke(null);
- libVersions.put("javafx", (String)version);
- libVersions.put("javafx (location)", fxPath.toString());
- } catch(Throwable e) {
- libVersions.put("javafx", "missing");
- libVersions.put("javafx (location)", "missing");
- }
-
- // Fallback to maven manifest information
- HashMap