diff --git a/.classpath b/.classpath index 0f6d86f21ee6f545513ec7fa4d4eb3f3a98045f6..bd7c971a1deead9c03d26c8f756bc34d5ba1dd11 100644 --- a/.classpath +++ b/.classpath @@ -16,7 +16,7 @@ <classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/> <classpathentry kind="lib" path="lib/args4j-2.33.jar"/> <classpathentry kind="lib" path="lib/flexjson-2.1/flexjson-2.1.jar" sourcepath="lib/flexjson-2.1/flexjson-2.1-sources.jar"/> - <classpathentry kind="lib" path="lib/proxy-vole/proxy-vole-1.0.5-SNAPSHOT-jar-with-dependencies.jar" sourcepath="lib/proxy-vole/proxy-vole-1.0.5-SNAPSHOT-sources.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry exported="true" kind="lib" path="lib/proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/> <classpathentry kind="output" path="target/classes"/> </classpath> diff --git a/.project b/.project index 7698d41ae54de7a284c2455f3bd5c1a9aac15c71..e78f869f7cae861a5907c2d95a9be922924045ef 100644 --- a/.project +++ b/.project @@ -12,9 +12,6 @@ </buildCommand> </buildSpec> <natures> - <nature>org.eclipse.jem.workbench.JavaEMFNature</nature> <nature>org.eclipse.jdt.core.javanature</nature> - <nature>org.eclipse.jem.beaninfo.BeanInfoNature</nature> - <nature>ch.acanda.eclipse.pmd.builder.PMDNature</nature> </natures> </projectDescription> diff --git a/CHANGES b/CHANGES index da9955c39a36ad881a73d93cd8b793a53f6d2393..88ee87d683c1670b29b09c793e7ef6d6a186b511 100644 --- a/CHANGES +++ b/CHANGES @@ -1,9 +1,21 @@ +v3.1 +---- + +- Auto-detection of proxy settings is now available. + +- Fix a bug which prevented executions when + simpleWorkflowPlanner_aggregate_activities is set. In particular, + this variable is set in the bridge so that the bridge sends the + largest possible workflow to the server. + + v3.0.2 ------ - Fix a bug causing an application to crash if no logging.properties could be found (*sigh*) + v3.0.1 ------ diff --git a/ant/dependencies.xml b/ant/dependencies.xml index 3183ca02e9685e001a9c4608df2e2fcec9b76deb..0e8b8a12a42fd54531082964f624100ed0b2f573 100644 --- a/ant/dependencies.xml +++ b/ant/dependencies.xml @@ -26,6 +26,7 @@ <filename name="woodstox-core-5.0.3.jar"/> <filename name="velocity-1.6.3-dep.jar"/> <filename name="velocity-1.6.3.jar"/> + <filename name="proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/> </or> </selector> @@ -56,6 +57,7 @@ <filename name="sqlite-jdbc-3.20.0.jar"/> <filename name="stax2-api-4.0.0.jar"/> <filename name="woodstox-core-5.0.3.jar"/> + <filename name="proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/> </or> </selector> <fileset dir="${praxis.core.lib}" id="praxis.server.dependencies"> @@ -75,6 +77,7 @@ <filename name="jdom.jar" /> <filename name="saxpath.jar" /> <filename name="org.apache.common.lang.SystemUtils.jar" /> + <filename name="proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/> </or> </selector> <fileset dir="${praxis.core.lib}" id="praxis.platform.dependencies"> diff --git a/build.xml b/build.xml index e56ac185a66bc0d31aaeae6c41fa99fd5e56f57f..66d8c6186d28b98e33672d6c2cf9757cba033463 100644 --- a/build.xml +++ b/build.xml @@ -7,7 +7,7 @@ <format property="build.time" pattern="yyyy-MM-dd'T'hh:mm:ss.SSSZ"/> </tstamp> - <property name="praxis.version" value="3.0.2"/> + <property name="praxis.version" value="3.1"/> <!-- If not called from an other project setting praxis.home, define it. In details: - it is unset when directly building the jars of Praxis, diff --git a/build/DATE b/build/DATE new file mode 100644 index 0000000000000000000000000000000000000000..7fb15a38ea4d0a47d80c444b0f7c81d9113f11ed --- /dev/null +++ b/build/DATE @@ -0,0 +1 @@ +2019-05-09 diff --git a/build/VERSION b/build/VERSION new file mode 100644 index 0000000000000000000000000000000000000000..8c50098d8aed57b02fd10f40a670a7c673b7c5a5 --- /dev/null +++ b/build/VERSION @@ -0,0 +1 @@ +3.1 diff --git a/build/build.sh b/build/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..2c3174d547b463db87e741bfe5f5ba15da02b504 --- /dev/null +++ b/build/build.sh @@ -0,0 +1,54 @@ +#! /bin/bash +set -e +VERSION=$(cat ${0%/*}/VERSION) +DATE=$(cat ${0%/*}/DATE) +GUI="../praxis-swing-gui" +cd "${0%/*}"/.. +BUILD_DATE=$(date --iso-8601=seconds) + +# NB: Changed files hereafter should be ignored by the version control, +# e.g. git update-index --assume-unchanged <file> +# or the commits retrieved here won't be the right ones +CORE_COMMIT=$(git describe --tags --always --broken) +GUI_COMMIT=$(cd "${GUI}" && git describe --tags --always --broken) + +sed -i -e 's#<property name="praxis.version" value="[^"]*"/>#<property name="praxis.version" value="'${VERSION}'"/>#' build.xml +sed -e '/public static final String release / s/"[^"]*"/"'${VERSION}'"/' \ + -i src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java +sed -e '/public static final String release_date / s/"[^"]*"/"'${DATE}'"/' \ + -i src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java +sed -e "/DATE/ s/=.*;$/= \"${BUILD_DATE}\";/" \ + -i src/eu/telecom_bretagne/praxis/common/BuildInfo.java +sed -e "/COMMIT/ s/=.*;$/= \"${CORE_COMMIT}\";/" \ + -i src/eu/telecom_bretagne/praxis/common/BuildInfo.java + +sed -e "/DATE/ s/=.*;$/= \"${BUILD_DATE}\";/" \ + -i ${GUI}/src/eu/telecom_bretagne/praxis/client/ui/BuildInfo.java +sed -e "/COMMIT/ s/=.*;$/= \"${GUI_COMMIT}\";/" \ + -i ${GUI}/src/eu/telecom_bretagne/praxis/client/ui/BuildInfo.java + +./data/i18n/native_to_ascii.sh +\rm -f target/jars/praxis.jar target/jars/praxis_server_platform.jar + +# even if the file is marked "assumed-unchanged", git describe marks it as +# dirty: refresh the index +( set +e; git update-index --refresh > /dev/null 2>&1 ; exit 0 ) +( set +e; cd "${GUI}" && git update-index --refresh > /dev/null 2>&1 ; exit 0) + +ant praxis.build.standalone.jar praxis.build.server_platform.jar + +NEW_CORE_COMMIT=$(git describe --tags --always --broken) +if [ "${CORE_COMMIT}" != "${NEW_CORE_COMMIT}" ]; then + echo "Warning: description of core commit changed!" + echo " ${CORE_COMMIT} -> ${NEW_CORE_COMMIT}" +fi +NEW_GUI_COMMIT=$(cd "${GUI}" && git describe --tags --always --broken) +if [ "${GUI_COMMIT}" != "${NEW_GUI_COMMIT}" ]; then + echo "Warning: description of GUI commit changed!" + echo " ${GUI_COMMIT} -> ${NEW_GUI_COMMIT}" +fi + + +echo Built ${CORE_COMMIT} / ${GUI_COMMIT} +# +exit 0 diff --git a/configurations/configuration.defaults b/configurations/configuration.defaults index 0eab0438d021942ff4125065118b4e822639938a..92bf8498740ac8b9595b81706c634b4255e744de 100644 --- a/configurations/configuration.defaults +++ b/configurations/configuration.defaults @@ -19,6 +19,9 @@ javax.net.ssl.trustStorePassword= rmi.useHTTP_BOOLEAN-CHECK_ +proxy.auto_detect.enabled=false +proxy.auto_detect.enabled_BOOLEAN-CHECK_ + # Whether the (stdin) console should be started or not console_BOOLEAN-CHECK_ console=false @@ -112,7 +115,7 @@ client.color.datasource.invalid=0xFF6464 client.color.focus=green # TODO shadow new Color(142,178,190,64); client.color.shadow=0x8EB2BE -#client.color.link=GRAY +client.color.link=BLACK client.color.link.focused=RED client.color.program.background=0xDCE7CD client.color.program.executed=0x85EE89 diff --git a/configurations/configuration.template b/configurations/configuration.template index c8f2a76a2ec80fd6ff5ac38857632e2d67a29b7e..a5b0ff9048ec9a6019f14d636b32626cc16377c2 100644 --- a/configurations/configuration.template +++ b/configurations/configuration.template @@ -20,6 +20,8 @@ javax.net.ssl.trustStorePassword= rmi.useHTTP=false rmi.useSSL=false +proxy.auto_detect.enabled=false + # Whether the (stdin) console should be started or not console=false diff --git a/data/i18n/native_to_ascii.sh b/data/i18n/native_to_ascii.sh index b6d0467b4d6667f9d9eb2678783b86379e6e24cf..f012b5d9ad288df82e2f7a154ed753f9cdfbdf40 100755 --- a/data/i18n/native_to_ascii.sh +++ b/data/i18n/native_to_ascii.sh @@ -5,7 +5,7 @@ shopt -s nullglob cd ${0%/*}/original for lang in el en es fr; do - t9n="praxis_${lang}" + t9n="praxis_${lang}.properties" encoding=("praxis_${lang}.encoding".*) encoding="${encoding##*.}" if [ -z "${encoding}" ]; then @@ -14,11 +14,11 @@ for lang in el en es fr; do fi echo "${t9n}: ${encoding} to ascii..." >&2 - native2ascii -encoding "${encoding}" "${t9n}" "../${t9n}.properties" + native2ascii -encoding "${encoding}" "${t9n}" "../${t9n}" # we use java.text.MessageFormat, escape simple quotes - sed -i -e "s/'/''/g" "../${t9n}.properties" + sed -i -e "s/'/''/g" "../${t9n}" # remove the emacs' coding system - sed -i -e '/^# *-\*- coding:/ d' "../${t9n}.properties" + sed -i -e '/^# *-\*- coding:/ d' "../${t9n}" done cd - diff --git a/data/i18n/original/README.dev b/data/i18n/original/README.dev new file mode 100644 index 0000000000000000000000000000000000000000..9c9376e1405de48b44a81c8dad3d2cbc3ac3fab2 --- /dev/null +++ b/data/i18n/original/README.dev @@ -0,0 +1,11 @@ +Java 9+: properties are loaded in UTF-8 by default. + +For now, even when Java 9+ is supported by Praxis, Java 8 is still the +default (https://www.java.com/fr/download/), so the only option we +will have will be to set +java.util.PropertyResourceBundle.encoding=ISO-8859-1 and build the jar +as usual. + +cf. https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm#JSINT-GUID-9DCDB41C-A989-4220-8140-DBFB844A0FCA +UTF-8 Properties Files +Internationalization Enhancements in JDK 9 diff --git a/data/i18n/original/praxis_el b/data/i18n/original/praxis_el.properties similarity index 99% rename from data/i18n/original/praxis_el rename to data/i18n/original/praxis_el.properties index dc3758fedd93a6b7be0060f8ff4d3d6cc71e7a5e..e6fefc1057068d3fe5b6ca7edad80d7693206220 100644 --- a/data/i18n/original/praxis_el +++ b/data/i18n/original/praxis_el.properties @@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label = Περιγραφή το UI.dialog.prg_properties.parameters = Παράμετροι: UI.dialog.prg_properties.parameters_default = (και η προεπιλεγμένη τιμή τους) UI.dialog.prg_properties.title = Ιδιότητες προγράμματος +UI.dialog.prg_properties.invalid_value = Μη έγκυρη τιμή +UI.dialog.prg_properties.invalid_integer_value = Μη έγκυρη τιμή: απαιτείται ακέραιος αριθμός +UI.dialog.prg_properties.invalid_float_value = Μη έγκυρη τιμή: απαιτείται αριθμός για το κυμαινόμενο σημείο UI.dialog.quit = Εγκαταλείψτε UI.dialog.quit_and_disconnect_msg = \n\ Θέλετε να εγκαταλείψετε;\n\ diff --git a/data/i18n/original/praxis_en b/data/i18n/original/praxis_en.properties similarity index 99% rename from data/i18n/original/praxis_en rename to data/i18n/original/praxis_en.properties index c895e75d1974e9d24cbeb193a4a4953d5bf16ab0..c1f073aacf4234c4ede25f4bf962061e9978f40c 100644 --- a/data/i18n/original/praxis_en +++ b/data/i18n/original/praxis_en.properties @@ -131,6 +131,9 @@ UI.dialog.prg_properties.main_label = Description of {0} (cli UI.dialog.prg_properties.parameters = Parameters: UI.dialog.prg_properties.parameters_default = (and their default value) UI.dialog.prg_properties.title = Program properties +UI.dialog.prg_properties.invalid_value = Invalid value +UI.dialog.prg_properties.invalid_integer_value = Invalid value: an integer number is required +UI.dialog.prg_properties.invalid_float_value = Invalid value: a floating point number is required UI.dialog.quit = Quit UI.dialog.quit_and_disconnect_msg = \n\ Do you want to quit?\n\ diff --git a/data/i18n/original/praxis_es b/data/i18n/original/praxis_es.properties similarity index 99% rename from data/i18n/original/praxis_es rename to data/i18n/original/praxis_es.properties index 478520d4e72c397935479e70a5ca575500f6dcfe..185d07c4b8173f74b5a2f73c6a2bea3f91983d0b 100644 --- a/data/i18n/original/praxis_es +++ b/data/i18n/original/praxis_es.properties @@ -137,6 +137,9 @@ UI.dialog.prg_properties.main_label = Descripci UI.dialog.prg_properties.parameters = Par�metros: UI.dialog.prg_properties.parameters_default = (y sus valores por defecto) UI.dialog.prg_properties.title = Propiedades del programa +UI.dialog.prg_properties.invalid_value = Valor no v�lido +UI.dialog.prg_properties.invalid_integer_value = Valor no v�lido: se requiere un n�mero entero +UI.dialog.prg_properties.invalid_float_value = Valor no v�lido: se requiere un n�mero de coma flotante UI.dialog.quit = Salir UI.dialog.quit_and_disconnect_msg = \n\ �Desea salir?\n\ diff --git a/data/i18n/original/praxis_fr b/data/i18n/original/praxis_fr.properties similarity index 99% rename from data/i18n/original/praxis_fr rename to data/i18n/original/praxis_fr.properties index 671478f1ca703f2eb9457ac43ad6e05506d5d9b6..ec412bfd24c6a6e9d96e4368428b03690a057bb8 100644 --- a/data/i18n/original/praxis_fr +++ b/data/i18n/original/praxis_fr.properties @@ -131,6 +131,9 @@ UI.dialog.prg_properties.main_label = Description de: {0} (cl UI.dialog.prg_properties.parameters = Paramètres : UI.dialog.prg_properties.parameters_default = (et leur valeur par défaut) UI.dialog.prg_properties.title = Propriétés de programme +UI.dialog.prg_properties.invalid_value = Valeur incorrecte +UI.dialog.prg_properties.invalid_integer_value = Valeur incorrecte: un nombre entier est requis +UI.dialog.prg_properties.invalid_float_value = Valeur incorrecte: un nombre r�el est requis UI.dialog.quit = Quitter UI.dialog.quit_and_disconnect_msg = \n\ Voulez-vous quitter l'application?\n\ diff --git a/data/i18n/praxis_el.properties b/data/i18n/praxis_el.properties index 911513ce4a5ee08e16ec1583a4374c7bde243f5f..e2b7f3802d100013cb4f6bb3789556fc182b79a4 100644 --- a/data/i18n/praxis_el.properties +++ b/data/i18n/praxis_el.properties @@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label = \u03a0\u03b5\u03c1\u03b9 UI.dialog.prg_properties.parameters = \u03a0\u03b1\u03c1\u03ac\u03bc\u03b5\u03c4\u03c1\u03bf\u03b9: UI.dialog.prg_properties.parameters_default = (\u03ba\u03b1\u03b9 \u03b7 \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03bb\u03b5\u03b3\u03bc\u03ad\u03bd\u03b7 \u03c4\u03b9\u03bc\u03ae \u03c4\u03bf\u03c5\u03c2) UI.dialog.prg_properties.title = \u0399\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2 \u03c0\u03c1\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03bf\u03c2 +UI.dialog.prg_properties.invalid_value = \u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03c4\u03b9\u03bc\u03ae +UI.dialog.prg_properties.invalid_integer_value = \u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03c4\u03b9\u03bc\u03ae: \u03b1\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b1\u03ba\u03ad\u03c1\u03b1\u03b9\u03bf\u03c2 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 +UI.dialog.prg_properties.invalid_float_value = \u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03c4\u03b9\u03bc\u03ae: \u03b1\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03bf \u03ba\u03c5\u03bc\u03b1\u03b9\u03bd\u03cc\u03bc\u03b5\u03bd\u03bf \u03c3\u03b7\u03bc\u03b5\u03af\u03bf UI.dialog.quit = \u0395\u03b3\u03ba\u03b1\u03c4\u03b1\u03bb\u03b5\u03af\u03c8\u03c4\u03b5 UI.dialog.quit_and_disconnect_msg = \n\ \u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03bb\u03b5\u03af\u03c8\u03b5\u03c4\u03b5;\n\ diff --git a/data/i18n/praxis_en.properties b/data/i18n/praxis_en.properties index ce0709ba29fe026d261c339e2bc9fc3c0da61df2..be19376ff9ba24c2fef8dcc39b66a4256775b35d 100644 --- a/data/i18n/praxis_en.properties +++ b/data/i18n/praxis_en.properties @@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label = Description of {0} (cli UI.dialog.prg_properties.parameters = Parameters: UI.dialog.prg_properties.parameters_default = (and their default value) UI.dialog.prg_properties.title = Program properties +UI.dialog.prg_properties.invalid_value = Invalid value +UI.dialog.prg_properties.invalid_integer_value = Invalid value: an integer number is required +UI.dialog.prg_properties.invalid_float_value = Invalid value: a floating point number is required UI.dialog.quit = Quit UI.dialog.quit_and_disconnect_msg = \n\ Do you want to quit?\n\ diff --git a/data/i18n/praxis_es.properties b/data/i18n/praxis_es.properties index e433475d2437fb5dfece12682559ad2bcd1d46db..1932acb219d0663ad79da1e40f2524cd82ebd7d7 100644 --- a/data/i18n/praxis_es.properties +++ b/data/i18n/praxis_es.properties @@ -136,6 +136,9 @@ UI.dialog.prg_properties.main_label = Descripci\u00f3n de {0} UI.dialog.prg_properties.parameters = Par\u00e1metros: UI.dialog.prg_properties.parameters_default = (y sus valores por defecto) UI.dialog.prg_properties.title = Propiedades del programa +UI.dialog.prg_properties.invalid_value = Valor no v\u00e1lido +UI.dialog.prg_properties.invalid_integer_value = Valor no v\u00e1lido: se requiere un n\u00famero entero +UI.dialog.prg_properties.invalid_float_value = Valor no v\u00e1lido: se requiere un n\u00famero de coma flotante UI.dialog.quit = Salir UI.dialog.quit_and_disconnect_msg = \n\ \u00bfDesea salir?\n\ diff --git a/data/i18n/praxis_fr.properties b/data/i18n/praxis_fr.properties index 067931db0127c1b9d81a9e74fa6ba02927430b4d..55b05e4e915ad9e33ab9a8776f1d29009ca4fe7d 100644 --- a/data/i18n/praxis_fr.properties +++ b/data/i18n/praxis_fr.properties @@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label = Description de: {0} (cl UI.dialog.prg_properties.parameters = Param\u00e8tres : UI.dialog.prg_properties.parameters_default = (et leur valeur par d\u00e9faut) UI.dialog.prg_properties.title = Propri\u00e9t\u00e9s de programme +UI.dialog.prg_properties.invalid_value = Valeur incorrecte +UI.dialog.prg_properties.invalid_integer_value = Valeur incorrecte: un nombre entier est requis +UI.dialog.prg_properties.invalid_float_value = Valeur incorrecte: un nombre r\ufffdel est requis UI.dialog.quit = Quitter UI.dialog.quit_and_disconnect_msg = \n\ Voulez-vous quitter l''application?\n\ diff --git a/src/eu/telecom_bretagne/praxis/client/Client.java b/src/eu/telecom_bretagne/praxis/client/Client.java index dbe02a3b820d5dcc02ca801afbd6a82a8fbbbf78..da60a82788c153922ab5373a5cfd365c55ef8121 100644 --- a/src/eu/telecom_bretagne/praxis/client/Client.java +++ b/src/eu/telecom_bretagne/praxis/client/Client.java @@ -157,7 +157,6 @@ public class Client implements ApplicationListener * @param workflow * @param zip * . It is deleted after the event has been sent. - * @return */ public void requestExecution(Result result) { @@ -352,7 +351,7 @@ public class Client implements ApplicationListener else error_title = "Unknown error"; - ErrorDialog.displayErrorMessage(error_title, error); + ErrorDialog.showErrorMessage(error_title, error); System.exit(-1);// TODO list & identify all exit status } connection_status.data = ( event.data instanceof Integer ); @@ -381,13 +380,18 @@ public class Client implements ApplicationListener e.printStackTrace(); } } - if (! (Boolean) connection_status.data) - cnx.disconnect(); - else + // The following line triggers a bug in eclipse (oxygen, photon) when e.g. trying to get this class' type + // hierarchy. + // This is related to https://bugs.eclipse.org/bugs/show_bug.cgi?id=474080 + // Note: the bug happens only if the condition is negated, and disappears when not doing anythiong but simply + // visiting Utils.java in an editor (Utils declares the SimpleContainer) + if ( connection_status.data != null && (Boolean) connection_status.data ) { if (delegate != null) delegate.authenticatedConnectionEstablished(); } + else + cnx.disconnect(); } /** diff --git a/src/eu/telecom_bretagne/praxis/client/ErrorDialog.java b/src/eu/telecom_bretagne/praxis/client/ErrorDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..5afc85d7b0595707d1cae3853832cf2999945850 --- /dev/null +++ b/src/eu/telecom_bretagne/praxis/client/ErrorDialog.java @@ -0,0 +1,60 @@ +package eu.telecom_bretagne.praxis.client; + +import java.awt.HeadlessException; + +import javax.swing.JOptionPane; + +import eu.telecom_bretagne.praxis.common.Log; + +public interface ErrorDialog +{ + + /* No need to check Configuration.getBoolean("client.no_gui"): it loads to much classes (incl. sun.rmi.* classes) + * and we want to be able to display something when called with a non-supported jre/jdk, so we'd better load as + * little classes as possible. */ + + /** + * Shows an error dialog message to the user. This includes: + * <ul> + * <li>opening a graphical dialog window displaying the error, + * <li>logging the error message at the {@link java.util.logging.Level#SEVERE <i>severe</i> level}, + * <li>printing the error message on the {@link System#err standard error}. + * </ul> + * + * @param title + * the title of the message, or header of the dialog window shown + * @param message + * the error message + */ + public static void showErrorMessage(String title, String message) + { + // print it & log it in any cases + System.err.println("Error: " + title + " - "+message); + Log.log.severe(()->title+" - "+message); + try { JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE); } + catch (HeadlessException e) { /* ignore */ } + } + + /** + * Show a warning message to the user. This includes: + * <ul> + * <li>opening a graphical dialog window displaying the warning, + * <li>logging the warning message at the {@link java.util.logging.Level#WARNING <i>warning</i> level}, + * <li>printing the warning message on the {@link System#err standard error}. + * </ul> + * + * @param title + * the title of the message, or header of the dialog window shown + * @param message + * the error message + */ + public static void showWarningMessage(String title, String message) + { + // print it & log it in any cases + System.err.println("Warning: " + title + " - "+message); + Log.log.warning(()->title+" - "+message); + try { JOptionPane.showMessageDialog(null, message, title, JOptionPane.WARNING_MESSAGE); } + catch (HeadlessException e) { /* ignore */ } + } + +} diff --git a/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java b/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java index 29ef561f5a82909fa940301232437191d257cdc7..1aa9b736393d8d821f7de31b011b7a996fa6504f 100644 --- a/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java +++ b/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java @@ -12,6 +12,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.stream.Stream; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; @@ -57,6 +59,8 @@ public class SimpleCommandLine extends StorageListenerAdapter public static final int DEBUG = 1; + static final String CLASS = SimpleCommandLine.class.getName(); + public static class DirectoryOptionHandler extends OptionHandler<File> { @@ -131,6 +135,12 @@ public class SimpleCommandLine extends StorageListenerAdapter throw new CmdLineException(null, "Invalid value \"" + $id_path + "\": expecting id=file"); try { + // a workflow interprets a relative path in an input as relative to the file it was loaded from, + // but the paths passed to option -i are relative to the current directory: we must store the + // absolute paths in the mapping instead. + id_path[1]=new File(id_path[1]).getAbsolutePath(); + if (options.verbose > DEBUG) + System.err.printf(String.format("mapping input %s to: %s\n", id_path)); inputMap.put(id_path[0], id_path[1]); } catch (NumberFormatException e) @@ -484,6 +494,7 @@ public class SimpleCommandLine extends StorageListenerAdapter public static Result executeAndGetResult(Workflow workflow) throws InvalidXMLException, IOException, InterruptedException { + Log.log.entering(CLASS, "executeAndGetResult", workflow); // execute: wait() on singleton, triggered by resultModified() executeWorkflow(workflow); @@ -494,13 +505,19 @@ public class SimpleCommandLine extends StorageListenerAdapter * as a consequence the result remains registered. * NB: it is deleted by a request made by the StorageManager */ - while (getAvailableResults(workflow).contains(result)) + Stream <Result> results = getAvailableResults(workflow).stream(); + while (results.anyMatch((aResult)->aResult.executionID().equals(result.executionID()))) + { + Log.log.finest("The result has not been deleted server-side yet"); try { Thread.sleep(50); } catch (InterruptedException e) - {} + { Log.exception.log(Level.INFO, "Interrupted", e); } + results = getAvailableResults(workflow).stream(); + } + Log.log.exiting(CLASS, "executeAndGetResult", result); return result; } @@ -576,6 +593,12 @@ public class SimpleCommandLine extends StorageListenerAdapter } /* Implementation of ServerMessageListener */ + /** + * Called when available results are received. When the message is in response to the request made by + * {@link #getAvailableResults(Workflow)}, that method is unblocked and returns the received results. + * + * @param anEvent the received event + */ @Override public void receivedAvailableResults(ServerToClientEvent anEvent) { diff --git a/src/eu/telecom_bretagne/praxis/client/StorageManager.java b/src/eu/telecom_bretagne/praxis/client/StorageManager.java index 94de30bf4e7df243053b5cf49ce26b1769685f9f..11e892d199b23c6e2048e951ef73b61f808fa35e 100644 --- a/src/eu/telecom_bretagne/praxis/client/StorageManager.java +++ b/src/eu/telecom_bretagne/praxis/client/StorageManager.java @@ -277,9 +277,8 @@ public class StorageManager /** * @param dir * @return - * @throws IllegalArgumentException - * if the directory has more than one file with the appropriate extension ( {@link Configuration - * configuration}'s key: file_extension) + * @throws IllegalArgumentException if the directory has no file or more than one file with the appropriate + * extension ( {@link Configuration configuration}'s key: file_extension) */ static private File workflowFileInDir(File dir) throws IllegalArgumentException { @@ -719,8 +718,7 @@ public class StorageManager try { wsFile = workflowFileInDir(executionDir); } - catch (IllegalArgumentException e) {} - if (wsFile==null) + catch (IllegalArgumentException iae) { /* on est dans le cas où on récupère les résultats d'une ancienne version de praxis: on n'a pas * le workflow initial dans l'objet Result, et il n'était pas non plus préalablement stocké dans le diff --git a/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java b/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java index ebe275c0f3967efa0740170dbb8894fbfadf4862..0ec202dc7a6b6d41e86d79fac35a20511754df65 100644 --- a/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java +++ b/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java @@ -13,8 +13,6 @@ public class ApplicationAdapter * @see eu.telecom_bretagne.praxis.client.ui.event.ApplicationListener#applicationClosing() */ @Override - public void applicationExiting() - { - } + public void applicationExiting() { /* does nothing */ } } diff --git a/src/eu/telecom_bretagne/praxis/common/CipherUtils.java b/src/eu/telecom_bretagne/praxis/common/CipherUtils.java index d7653f0b85a9bc170849a94b2eaf235e1a3a6626..8cf9795210e09d44956a5b8b50e394a3dfd7b6b4 100644 --- a/src/eu/telecom_bretagne/praxis/common/CipherUtils.java +++ b/src/eu/telecom_bretagne/praxis/common/CipherUtils.java @@ -75,7 +75,9 @@ public class CipherUtils public static InputStream decryptedStream(String password, File input) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { - return decryptedStream(password, new FileInputStream(input)); + try (InputStream is = new FileInputStream(input)) { + return decryptedStream(password, is); + } } protected static InputStream decryptedStream(String password, InputStream stream) diff --git a/src/eu/telecom_bretagne/praxis/common/FileResources.java b/src/eu/telecom_bretagne/praxis/common/FileResources.java index 23918d5ba64b37435d1429d8a6888181b9426833..18f30f93f4d0293825a7803c2f2b8f87e4d88d05 100644 --- a/src/eu/telecom_bretagne/praxis/common/FileResources.java +++ b/src/eu/telecom_bretagne/praxis/common/FileResources.java @@ -130,9 +130,10 @@ public class FileResources { * To avoid I/O errors such as files not existing, the supplied resource * should have been retrieved using {@link #file(String)}. * @param ciphered whether the resource is expected to be ciphered or not. - * @return the appropriate input stream, decyphered if parameter ciphered is true. + * @return the appropriate input stream, deciphered if parameter ciphered is true. * @throws ResourceNotFoundException */ + @SuppressWarnings("resource") public static InputStream inputStreamForResource(File resource, boolean ciphered) throws ResourceNotFoundException { diff --git a/src/eu/telecom_bretagne/praxis/common/Launcher.java b/src/eu/telecom_bretagne/praxis/common/Launcher.java index d5856175b477034535c113e017333dee4a283113..69a342b02dde9c949916ed5cf81299c2d9ba650a 100644 --- a/src/eu/telecom_bretagne/praxis/common/Launcher.java +++ b/src/eu/telecom_bretagne/praxis/common/Launcher.java @@ -37,8 +37,7 @@ public class Launcher * @param platform indicates whether initialization specific to the platform-side should be performed */ public void initialize(boolean client, boolean server, boolean platform) - { - } + { /* does nothing */ } } /** @@ -82,7 +81,7 @@ public class Launcher // we do not want to display anything for mac os x / vendor="Apple Inc.", the jvm shipped with mac os is okay. // since java 7, vendor is Oracle Corporation if (!"Sun Microsystems Inc.".equals(vendor) && !"Apple Inc.".equals(vendor) && !"Oracle Corporation".equals(vendor)) - ErrorDialog.displayWarningMessage("JVM Warning", + ErrorDialog.showWarningMessage("JVM Warning", "We strongly recommend that you use a Java Virtual Machine provided by Oracle!\n\n" + "You're currently using the following JVM:\n - version: " + version @@ -92,7 +91,7 @@ public class Launcher else if (jvmVersion >= 9) { - ErrorDialog.displayErrorMessage("Error", + ErrorDialog.showErrorMessage("Error", "Error: this application requires java 8 but java "+jvmVersion+" is used."); System.exit(-2); } @@ -100,17 +99,6 @@ public class Launcher Log.log.info(()->"Running with JVM version " + version + " by " + vendor + ", fine"); } - /** - * Workaround for bug #7188755 (bugs.sun.com). - * @see ProxySelectorWrapper ProxySelectorWrapper for details - */ - public static void workaroundBug7188755() - { - ProxySelector defaultProxySelector = ProxySelector.getDefault(); - if (defaultProxySelector!=null) - ProxySelector.setDefault(new ProxySelectorWrapper(defaultProxySelector)); - } - public static void fixWmClass() { // cf. http://elliotth.blogspot.fr/2007/02/fixing-wmclass-for-your-java.html @@ -168,9 +156,10 @@ public class Launcher } checkJVM(); - workaroundBug7188755(); fixWmClass(); + ProxyAutoDetect.initialize(); + if ( Configuration.isDefined("client") && Configuration.isDefined("servers") && Configuration.isDefined("platforms")) @@ -199,7 +188,7 @@ public class Launcher } catch (Throwable t) { - ErrorDialog.displayErrorMessage("Connection error", + ErrorDialog.showErrorMessage("Connection error", "Error: unable to connect to the server\nReason: "+t.toString()); System.exit(1); } diff --git a/src/eu/telecom_bretagne/praxis/common/Log.java b/src/eu/telecom_bretagne/praxis/common/Log.java index 76bdc767f5c860670983846a4e5dfd0cdd924e66..2ab04f77b73b48426c8adfdc48621e310f8c507f 100644 --- a/src/eu/telecom_bretagne/praxis/common/Log.java +++ b/src/eu/telecom_bretagne/praxis/common/Log.java @@ -9,8 +9,10 @@ public class Log * NB: Log levels are always localized * https://stackoverflow.com/questions/3920930/java-util-logging-how-to-set-level-by-logger-package-or-prefix */ - public static final Logger log = Logger.getLogger("praxis", null); + public static final Logger log = Logger.getLogger("praxis", null); public static final Logger migration = Logger.getLogger("praxis.migration"); + public static final Logger exception = Logger.getLogger("exception.ignored", null); + } diff --git a/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java b/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java index 194baac4d25de85f2ae028f5bc527e8155d10d1d..29130083475559e527d7e090457d2110fa213217 100644 --- a/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java +++ b/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java @@ -58,14 +58,14 @@ public class PraxisPreferences * The default implementation does nothing. * @see #initCommon() */ - public void initClient() {} + public void initClient() { /* does nothing */ } /** * Called by the framework at initialization time. Subclass this method if you need to add you own values to * the application's preferences. This method is always called when the preferences are initialized.<br> * The default implementation does nothing. */ - public void initCommon() {} + public void initCommon() { /* does nothing */ } } protected static final Preferences PRAXIS_ROOT_NODE; diff --git a/src/eu/telecom_bretagne/praxis/common/ProxyAutoDetect.java b/src/eu/telecom_bretagne/praxis/common/ProxyAutoDetect.java new file mode 100644 index 0000000000000000000000000000000000000000..51c730e5b62af7bf01ef42bdfbc97445f4d67e3a --- /dev/null +++ b/src/eu/telecom_bretagne/praxis/common/ProxyAutoDetect.java @@ -0,0 +1,64 @@ +package eu.telecom_bretagne.praxis.common; + +import java.net.ProxySelector; + +import org.apache.commons.lang.SystemUtils; + +import com.github.markusbernhardt.proxy.ProxySearch; +import com.github.markusbernhardt.proxy.ProxySearch.Strategy; + +public class ProxyAutoDetect +{ + /** + * Initializes the proxy auto-detection by setting the {@link ProxySelector#setDefault(ProxySelector) default proxy + * selector}. If the configuration item {@code proxy.auto_detect.enabled} is false, it does nothing. + */ + public static void initialize() + { + if ( ! Configuration.getBoolean("proxy.auto_detect.enabled")) + return; + + ProxySelector.setDefault(ProxyAutoDetect.getDefaultProxySearch().getProxySelector()); + } + + static ProxySearch getDefaultProxySearch() + { + final ProxySearch proxySearch = new ProxySearch(); // https://github.com/MarkusBernhardt/proxy-vole + + /* + * NB: Strategy BROWSER: is equivalent to IE on windows, and FIREFOX on others + * See source code for + * - com.github.markusbernhardt.proxy.ProxySearch#addStrategy(Strategy) + * - com.github.markusbernhardt.proxy.ProxySearch#getDefaultBrowserStrategy() + * - com.github.markusbernhardt.proxy.util.PlatformUtil#getDefaultBrowser() + */ + if ( SystemUtils.IS_OS_LINUX ) + { + proxySearch.addStrategy(Strategy.JAVA); + proxySearch.addStrategy(Strategy.OS_DEFAULT); + proxySearch.addStrategy(Strategy.GNOME); + proxySearch.addStrategy(Strategy.KDE); + proxySearch.addStrategy(Strategy.FIREFOX); + proxySearch.addStrategy(Strategy.ENV_VAR); + } + else if ( SystemUtils.IS_OS_WINDOWS ) + { + proxySearch.addStrategy(Strategy.JAVA); + proxySearch.addStrategy(Strategy.OS_DEFAULT); + proxySearch.addStrategy(Strategy.WIN); + proxySearch.addStrategy(Strategy.FIREFOX); + proxySearch.addStrategy(Strategy.IE); + proxySearch.addStrategy(Strategy.ENV_VAR); + } + else + { + proxySearch.addStrategy(Strategy.JAVA); + proxySearch.addStrategy(Strategy.OS_DEFAULT); + proxySearch.addStrategy(Strategy.FIREFOX); + proxySearch.addStrategy(Strategy.ENV_VAR); + } + // TODO WPAD ? quand est-ce que c'est appelé dans l'auto-détection? + return proxySearch; + } + +} diff --git a/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java b/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java index a927ce6783d054fb11bcf19ec64de9388ae44d42..bb80a639c36c0e80f0f8c9e3c05c996247428208 100644 --- a/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java +++ b/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java @@ -7,9 +7,9 @@ package eu.telecom_bretagne.praxis.common; */ public abstract class ReleaseInfo { - public static final String release = "3.0.2"; + public static final String release = "3.1"; - public static final String release_date = "2018-07-26"; + public static final String release_date = "2019-05-09"; public static final int application_revision = Configuration.getInt("revision"); diff --git a/src/eu/telecom_bretagne/praxis/common/SplashWindow.java b/src/eu/telecom_bretagne/praxis/common/SplashWindow.java index f49401baa7816e40403d7af7c6b8cdceea170f7e..64886df0466af1f0c921e1bd3b7c8130c1837416 100644 --- a/src/eu/telecom_bretagne/praxis/common/SplashWindow.java +++ b/src/eu/telecom_bretagne/praxis/common/SplashWindow.java @@ -27,6 +27,7 @@ import java.awt.Window; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Rectangle2D; +import java.util.logging.Level; import eu.telecom_bretagne.praxis.common.FileResources.ResourceNotFoundException; @@ -109,7 +110,7 @@ public class SplashWindow mt.waitForID(0); } catch (InterruptedException ie) - {} + { Log.exception.log(Level.INFO, "Interrupted", ie); } // Center the window on the screen int imgWidth = image.getWidth(this); @@ -234,7 +235,7 @@ public class SplashWindow instance.wait(); } catch (InterruptedException e) - {} + { Log.exception.log(Level.INFO, "Interrupted", e); } } } } diff --git a/src/eu/telecom_bretagne/praxis/common/SystemExecution.java b/src/eu/telecom_bretagne/praxis/common/SystemExecution.java index 31e1b859ca00d83070e3e9af8a38542540f3da9f..d159d9c8aece50c331c3c8c7fb26ecfce837970c 100644 --- a/src/eu/telecom_bretagne/praxis/common/SystemExecution.java +++ b/src/eu/telecom_bretagne/praxis/common/SystemExecution.java @@ -241,7 +241,7 @@ public class SystemExecution * @param stderr_limit * the maximum number of bytes to read from the standard error. If 0 or negative, no limitation * applies. - * @param delegate + * @param aDelegate * Uses a different delegate than the {@link #setDelegate(Delegate) global one}: in some particular * situations this is sometimes desirable to use a different delegate than the one used almost * everywhere. @@ -251,14 +251,14 @@ public class SystemExecution * @throws IllegalStateException * if executed more than once. */ - public int execute(Writer stdoutWriter, long stdout_limit, Writer stderrWriter, long stderr_limit, Delegate delegate) + public int execute(Writer stdoutWriter, long stdout_limit, Writer stderrWriter, long stderr_limit, Delegate aDelegate) throws InterruptedException, IllegalStateException { // System.getenv() is unmodifiable: we need a copy Map<String, String> environment = new HashMap<String, String>(System.getenv()); - if (delegate != null) - cmd_array = delegate.prepareForExecution(cmd_array, environment); + if (aDelegate != null) + cmd_array = aDelegate.prepareForExecution(cmd_array, environment); /* Create String[] from Map */ // NB: do NOT initialize it here with a new String[] array, or, if the following condition are not satisfied, diff --git a/src/eu/telecom_bretagne/praxis/common/SystemInformations.java b/src/eu/telecom_bretagne/praxis/common/SystemInformations.java index 1a2c60fcb76f8e43d1e6fb1a0e6584737b231833..af748cf0136399ae5ec14dd60ad59998c425d0fb 100644 --- a/src/eu/telecom_bretagne/praxis/common/SystemInformations.java +++ b/src/eu/telecom_bretagne/praxis/common/SystemInformations.java @@ -295,6 +295,7 @@ public class SystemInformations } } + /** * Implements the {@link #detectProxy(Data)} method. */ @@ -303,38 +304,8 @@ public class SystemInformations System.err.println("_detectProxy() start"); final Data proxyDetectionData = network.add("proxy detection"); - final ProxySearch proxySearch = new ProxySearch(); // https://github.com/MarkusBernhardt/proxy-vole - - /* - * NB: Strategy BROWSER: is equivalent to IE on windows, and FIREFOX on others - * See source code for - * - com.github.markusbernhardt.proxy.ProxySearch#addStrategy(Strategy) - * - com.github.markusbernhardt.proxy.ProxySearch#getDefaultBrowserStrategy() - * - com.github.markusbernhardt.proxy.util.PlatformUtil#getDefaultBrowser() - */ - if ( SystemUtils.IS_OS_LINUX ) - { - proxySearch.addStrategy(Strategy.OS_DEFAULT); - proxySearch.addStrategy(Strategy.GNOME); - proxySearch.addStrategy(Strategy.KDE); - proxySearch.addStrategy(Strategy.FIREFOX); - proxySearch.addStrategy(Strategy.ENV_VAR); - } - else if ( SystemUtils.IS_OS_WINDOWS ) - { - proxySearch.addStrategy(Strategy.OS_DEFAULT); - proxySearch.addStrategy(Strategy.WIN); - proxySearch.addStrategy(Strategy.FIREFOX); - proxySearch.addStrategy(Strategy.IE); - } - else - { - proxySearch.addStrategy(Strategy.OS_DEFAULT); - proxySearch.addStrategy(Strategy.FIREFOX); - proxySearch.addStrategy(Strategy.ENV_VAR); - } - // TODO WPAD ? quand est-ce que c'est appelé dans l'auto-détection? - + ProxySearch proxySearch = ProxyAutoDetect.getDefaultProxySearch(); + Proxy proxy; // http proxy = _detectProxyForURL(proxySearch.getProxySelector(), CHECK_HTTP_URI, proxyDetectionData.add("http")); diff --git a/src/eu/telecom_bretagne/praxis/common/Utile.java b/src/eu/telecom_bretagne/praxis/common/Utile.java index b86ba0a488329fa510efdcf3d36ca667f338f245..552436926168c932cc2f462c76e3a4f830be6091 100644 --- a/src/eu/telecom_bretagne/praxis/common/Utile.java +++ b/src/eu/telecom_bretagne/praxis/common/Utile.java @@ -6,6 +6,7 @@ import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -508,14 +509,6 @@ public class Utile */ } - public static java.awt.Dimension textDimension(java.awt.Component c, java.awt.Font font, String txt) - { - java.awt.font.FontRenderContext fontRenderContext = ((java.awt.Graphics2D) c.getGraphics()) - .getFontRenderContext(); - java.awt.geom.Rectangle2D r = new java.awt.font.TextLayout(txt, font, fontRenderContext).getBounds(); - return new java.awt.Dimension((int) r.getWidth(), (int) r.getHeight()); - } - /** * Turns every byte in the array into its 2 characters hexadecimal representation, and returns the corresponding * string. @@ -965,8 +958,7 @@ public class Utile try { execution.execute(new StringWriter(), -1, null, -1); appPaths32 = execution.getStdout().toString().toLowerCase(); - } catch (InterruptedException e) { - } + } catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); } } if (appPaths6432Node==null) { @@ -975,8 +967,7 @@ public class Utile try { execution.execute(new StringWriter(), -1, null, -1); appPaths6432Node = execution.getStdout().toString().toLowerCase(); - } catch (InterruptedException e) { - } + } catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); } } /* @@ -1129,6 +1120,25 @@ public class Utile throw new IllegalArgumentException("There are unbalanced quotes"); return args.toArray(new String[args.size()]); } + + /** + * Calls {@link Closeable#close()} and ignore any IOException raised. + * @param closable the input stream to be closed. It may be {@code null}. + */ + public static void closeSilently(Closeable closable) + { + if ( closable == null ) + return; + try + { + closable.close(); + } + catch (IOException e) + { + Log.log.log(Level.FINE, "exception ignored", e); + } + } + public static void main(String[] args) { String test = "cmd -p'v1' --p3=\"v\"'\"'\"3\"";//"cmd -p'v1' --p3=\"v'3\""; diff --git a/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java index 7f283b7b66e244144fb2bb993310b44890df3a09..ab15412df23316562007dcf1dbd990fa9d98d6b5 100644 --- a/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java +++ b/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java @@ -26,7 +26,7 @@ public class DirectCommunicationFacade extends CommunicationFacade * Static initializer is empty: client and platform connects to the server * using the accept() method */ - static {} + static { /* left intentionally empty */ } public static void accept(DirectCommunicationFacade platformFacade) { @@ -116,7 +116,7 @@ public class DirectCommunicationFacade extends CommunicationFacade while (other_end == null && !disconnected) synchronized(this) { - try{ wait(1); } catch (InterruptedException e) {} + try{ wait(1); } catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); } } final ArrayList <Event> events_copy = new ArrayList<Event>(); while (other_end != null && !disconnected) { diff --git a/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java index 1e90dd33f588f63a8e18b7f12cbb23d5a8131d6a..5aaf65d8f5c47223582314a58b0d458c04292cc0 100644 --- a/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java +++ b/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java @@ -463,7 +463,7 @@ public class RMICommunicationFacade wait(1); } catch (InterruptedException e) - {} + { Log.exception.log(Level.INFO, "Interrupted", e); } } Log.log.info("Client is connected: thread starts polling the server for events"); while (isConnected()) @@ -475,7 +475,7 @@ public class RMICommunicationFacade serialized_event = clientCnxToServer.retrieveEvent(); /* wait a little, if and only if we did not receive anything */ try { if (serialized_event==null) Thread.sleep(500); } - catch (InterruptedException e) {} + catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); } } catch (Exception e) { diff --git a/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java index e70bb4db2685459bb826cde8f2c9e5fb430e4005..cd1ff50a23c9cc54a06da320d48243e0ed644a19 100644 --- a/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java +++ b/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java @@ -47,6 +47,7 @@ public class SSLSocketCommunicationFacade Log.log.info(()->"SSL Socket server started on port "+port); while (true) { + @SuppressWarnings("resource") // socket is intentionally not closed here! Socket socket = serverSocket.accept(); SocketCommunicationFacade cnx = new SocketCommunicationFacade("Server (socket SSL)", socket); new Server(cnx); diff --git a/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java b/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java index 18f3ed18d127bd3637f177fb1e2aeb3c44a62e4e..d790fbf04211636e43b6f519534e35647b06b8a5 100644 --- a/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java +++ b/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java @@ -26,7 +26,7 @@ import eu.telecom_bretagne.praxis.core.workflow.WorkflowID; * </ul> * <li>LIST_OF_AVAILABLE_RESULTS: sets username and workflow * <ul> - * <li>{@link Event#data}: List of {@link Result} + * <li>{@link Event#data}: a non-null list of {@link Result} * <li>{@link Event#file_conveyor}: not used * </ul> * <li>MESSAGE: sets username and workflow diff --git a/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java index 38947f5bc252c2460d0337d03214e15987856a6d..2682478dc2a2947b0bc01559d3194f89441c704b 100644 --- a/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java +++ b/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java @@ -51,6 +51,7 @@ public class SocketCommunicationFacade Log.log.info(()->"Socket server started on port "+port); while (true) { + @SuppressWarnings("resource") // socket is intentionally not closed here! Socket socket = serverSocket.accept(); SocketCommunicationFacade cnx = new SocketCommunicationFacade("Server (socket)", socket); new Server(cnx); @@ -125,7 +126,7 @@ public class SocketCommunicationFacade while (!isConnected()) synchronized(this) { - try{ wait(1); } catch (InterruptedException e) {} + try{ wait(1); } catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); } } int successive_failure = 0; while (isConnected()) { diff --git a/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java b/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java index 6fb767452dcbe66bc810477dfc12d814a9296a13..827a0fe7f08473b75c458f21afede7e61344d8ac 100644 --- a/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java +++ b/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java @@ -206,4 +206,10 @@ public class ExecutionSet extends AbstractSet<Program> implements java.io.Serial }); return sortedPrograms; } + + @Override + public String toString() + { + return super.toString() + " tag: " + ( tag == null ? "<null>" : tag.toString() ); + } } diff --git a/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java b/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java index 36d08889885790d85bd4961915a87893d1bca450..39707f9aba0db1327b6b7350fc565c00b5bd577d 100644 --- a/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java +++ b/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java @@ -397,12 +397,20 @@ public class ResultStore } } + /** + * Returns the results available for the supplied workflow and user. The returned results' + * {@link Result#zipFile()} is always null. + * + * @param workflowID the workflow ID for which results + * @param username the username + * @return list of the available results. It may be null if the results could not be retrieved from the store. + */ public ArrayList<Result> getResultsSummaryForWorkflow(WorkflowID workflowID, String username) { synchronized(db_connection) { String select = "SELECT * FROM " + RESULT + " WHERE " + RESULT_scid + "=? AND "+RESULT_user+"=?"; - ArrayList <Result>summary = new ArrayList<Result>(); + final ArrayList <Result> summary = new ArrayList<Result>(); try (PreparedStatement st = db_connection.prepareStatement(select)) { st.setString(1, workflowID.dumpID()); @@ -432,12 +440,18 @@ public class ResultStore } } + /** + * Returns the results available for a given user. The returned results' {@link Result#zipFile()} are always null. + * + * @param username the user name + * @return list of the available results. It may be null if the results could not be retrieved from the store. + */ public ArrayList<Result> getResultsSummaryForUser(String username) { synchronized(db_connection) { String select = "SELECT * FROM " + RESULT + " where " + RESULT_user + "=?"; - ArrayList <Result>summary = new ArrayList<Result>(); + final ArrayList<Result> summary = new ArrayList<Result>(); try (PreparedStatement st = db_connection.prepareStatement(select)) { st.setString(1, username); diff --git a/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java b/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java index ed7bccf3e0b5e608dd2a40a5e4a56bfdef3e5cb3..252afd12c4232dc449885f3dfe1e2b0a30da9c7d 100644 --- a/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java +++ b/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java @@ -57,7 +57,8 @@ public class SimpleWorkflowPlanner for (Long tag=1L; tag<=max_tag; tag++) { - for (Activity a: new ArrayList<Activity>(process.activities)) // decideExecSet() may modify the list + final ArrayList<Activity> activities = new ArrayList<Activity>(process.activities); + for (Activity a: activities) // decideExecSet() may modify the list { if (a.getContainer()==null) // activity has been merged into an other one and is not in the process anymore continue; @@ -149,9 +150,15 @@ public class SimpleWorkflowPlanner } // Finally, assign all predecessors to the same platform as activity: merge them + // The resulting activity gets the smallest tag value of all the merged activities. + Long tag = (Long) activity.getExecutionSet().getTag(); for (Activity predecessor: predecessors) { + final Long pred_tag = (Long) predecessor.getExecutionSet().getTag(); activity = process.merge(activity, predecessor); + if (pred_tag < tag) + tag = pred_tag; + activity.getExecutionSet().setTag(tag); } } diff --git a/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java b/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java index 262a7893ca81a72f9e8bf4cc0e8fe81ba239639e..b8db35f9bd490d222add05286c06ad4c13edb015 100644 --- a/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java +++ b/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java @@ -26,6 +26,7 @@ import org.jdom.JDOMException; import org.jdom.xpath.XPath; import eu.telecom_bretagne.praxis.common.Facade_xml; +import eu.telecom_bretagne.praxis.common.I18N; import eu.telecom_bretagne.praxis.common.InvalidXMLException; import eu.telecom_bretagne.praxis.common.InvalidXMLException.ELEMENT_TYPE; import eu.telecom_bretagne.praxis.core.workflow.Parameter; @@ -323,6 +324,7 @@ public class ParameterDescription implements Serializable * @param value * the value to check * @return true if the value is valid with respect to the parameter's type + * @see #getValueConstraintMessage() */ public boolean isaValidValue_wrtType(String value) { @@ -604,7 +606,27 @@ public class ParameterDescription implements Serializable return valueConstraintDescription; } - /** + /** + * Returns the message to display when the value is {@link #isaValidValue(String) invalid}. + * + * @return either the {@link #getValueConstraintDescription() description of the constraint}, or a default message + * if the latter is null or empty. + */ + public String getValueConstraintMessage() { + if ( valueConstraintDescription != null && ! "".equals(valueConstraintDescription) ) + return valueConstraintDescription; + switch (type) + { + case FLOAT: + return I18N.s("UI.dialog.prg_properties.invalid_float_value"); + case INT: + return I18N.s("UI.dialog.prg_properties.invalid_integer_value"); + default: + return I18N.s("UI.dialog.prg_properties.invalid_value"); + } + } + + /** * Parses the value constraint and transforms it into a valid java boolean expression. The built expression * determines whether a given value is valid wrt. the constraint; this value is named <code>value</code> in the * built expression. diff --git a/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java b/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java index 7be85f13cb782e5684b777fbdb3907b078b67c96..2b07ba522ce4b3c59dd78f9efca2609a5c8a206d 100644 --- a/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java +++ b/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java @@ -604,6 +604,11 @@ public class Parameter implements Cloneable, PropertyChangeListener, java.io.Ser return p; } + public String toString() + { + return "[Parameter ref_id:"+ref_id+"]"; + } + /* PropertyChangeSupport listeners & */ public void addPropertyChangeListener(PropertyChangeListener listener) { diff --git a/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java b/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java index c0fe672bb3acd5a90655b0e384a13402c5764fb8..582e82c2811e4fd5f65d848e93c76dc0309a800d 100644 --- a/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java +++ b/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java @@ -96,7 +96,7 @@ public class PlatformToClientBridge Log.log.severe(()->error_title+": "+error); - ErrorDialog.displayErrorMessage(error_title, error); + ErrorDialog.showErrorMessage(error_title, error); System.exit(-1);// TODO list & identify all exit status } } @@ -161,7 +161,7 @@ public class PlatformToClientBridge { // this is the result of an execution that was not sent by us. It may come from a different configuration // where the bridge is not activated. Log it and send it as-is. - Log.log.info(()->"Received a result with result.data==null. This cant be for use. "+result); + Log.log.info(()->"Received a result with result.data==null. This was not sent by the bridge. "+result); } this.sendResults(result); if (result.data!=null && result.getStatus().isClosed()) @@ -197,7 +197,7 @@ public class PlatformToClientBridge public void receivedMessage(ServerToClientEvent event) { if (event.forward) - ErrorDialog.displayWarningMessage("Message from server", (String)((Object[]) event.data)[0]); + ErrorDialog.showWarningMessage("Message from server", (String)((Object[]) event.data)[0]); } @Override diff --git a/src/eu/telecom_bretagne/praxis/server/Client.java b/src/eu/telecom_bretagne/praxis/server/Client.java index 4dc837ece2a50e1b80d826ee22c55e39440a5f6e..886ed3af6bd92f5f022d842471bf3c0d0728d1e1 100644 --- a/src/eu/telecom_bretagne/praxis/server/Client.java +++ b/src/eu/telecom_bretagne/praxis/server/Client.java @@ -9,6 +9,7 @@ import static eu.telecom_bretagne.praxis.common.events.ServerToClientEvent.Type. import java.io.Serializable; import java.util.ArrayList; +import java.util.logging.Level; import eu.telecom_bretagne.praxis.common.Log; import eu.telecom_bretagne.praxis.common.ReleaseInfo; @@ -81,7 +82,7 @@ public class Client implements Requester // can happen before the message is delivered TODO should be fixed Thread.sleep(500); } - catch (InterruptedException e) {} + catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); } cnx.disconnect(); } @@ -154,8 +155,8 @@ public class Client implements Requester ServerToClientEvent event = new ServerToClientEvent(LIST_OF_AVAILABLE_RESULTS); event.workflowID = workflowID; ArrayList<Result> results = Serveur.resultStore().getResultsSummaryForWorkflow(workflowID, login); - if (results==null || results.isEmpty()) - return; + if (results == null) + results = new ArrayList<>(); // method getResultsSummaryForWorkflow() returns results w/ null zipFile, we want to make it explicit that // zipFile should not be sent. for (Result result: results) diff --git a/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java b/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java index df304aee153b808056c3ffa15613359554c8e29b..b1fd99dff39cc7947e15f71a2ae1c33a1b8d8c11 100644 --- a/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java +++ b/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java @@ -106,7 +106,7 @@ public abstract class ExecutionEngine /** An execution progress monitor doing nothing whose operations are no-op */ public static final ExecutionProgressMonitor noopProgressMonitor = new ExecutionProgressMonitor() { - @Override public void setProgress(Result result) { } + @Override public void setProgress(Result result) { /* no-op */ } }; /** diff --git a/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java b/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java index f3188496716c39161f7bb2461080e501e643a265..29c19af8dbf25adb9ed7723b14a03fe38d8d379b 100644 --- a/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java +++ b/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java @@ -20,13 +20,13 @@ public class EventAuditTest */ @Before public void setUp() throws Exception - {} + { ; } /** * @throws java.lang.Exception */ @After public void tearDown() throws Exception - {} + { ; } } diff --git a/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java b/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java index 6464dff1e261a62c7dd9a893f112678d15da40c7..9704cbcab310dd63cf27e20c298dc063f8a11188 100644 --- a/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java +++ b/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java @@ -11,8 +11,6 @@ import static org.junit.Assert.assertTrue; import java.util.Arrays; -import org.junit.After; -import org.junit.Before; import org.junit.Test; import eu.telecom_bretagne.praxis.core.execution.ExecutionSet.ProgramInfo; @@ -24,16 +22,6 @@ import eu.telecom_bretagne.praxis.core.workflow.Program; */ public class ExecutionSetTest { - @Before - public void setUp() - { - } - - @After - public void cleanUp() - { - } - @Test public void addToSet() { diff --git a/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java b/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java index 5def8df6d38e275af6be4d55fe884a267ac6a6fb..2d534e1d1588c5a102798637c8c74a5f63baec6a 100644 --- a/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java +++ b/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java @@ -1,7 +1,6 @@ /* License: please refer to the file README.license located at the root directory of the project */ package eu.telecom_bretagne.praxis.core.execution; -import org.junit.Before; import org.junit.Test; import eu.telecom_bretagne.praxis.core.execution.Activity; @@ -30,12 +29,6 @@ public class ProcessTest super(null,null); } - @Before - public void SetUp() - { - - } - @Test public void activityHasaDefaultContext() {