diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ZoneCombinerComp.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ZoneCombinerComp.java index 972f4c582a..c38190e332 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ZoneCombinerComp.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ZoneCombinerComp.java @@ -28,6 +28,12 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; import java.util.regex.Matcher; import org.eclipse.jface.preference.IPreferenceStore; @@ -57,7 +63,6 @@ import org.opengis.referencing.FactoryException; import org.opengis.referencing.operation.TransformException; import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation; -import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException; import com.raytheon.uf.common.dataplugin.gfe.server.notify.CombinationsFileChangedNotification; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; @@ -106,6 +111,7 @@ import com.raytheon.viz.gfe.ui.zoneselector.ZoneSelector; * Changed to use CombinationsFileChangedNotification instead of * FileUpdatedMessage so we can ignore our own changes * Moved retrieval of combinations file to CombinationsFileUtil.init + * Oct 07, 2015 #4695 dgilling Move loading of combinations file off UI thread. * * * @@ -233,6 +239,8 @@ public class ZoneCombinerComp extends Composite implements IZoneCombiner { private AbstractGFENotificationObserver comboChangeListener; + private final ExecutorService asyncExecutor; + private void initPreferences() { IPreferenceStore prefs = Activator.getDefault().getPreferenceStore(); @@ -276,6 +284,8 @@ public class ZoneCombinerComp extends Composite implements IZoneCombiner { mapRequired = false; } + this.asyncExecutor = Executors.newCachedThreadPool(); + initPreferences(); init(); @@ -303,6 +313,7 @@ public class ZoneCombinerComp extends Composite implements IZoneCombiner { ZoneCombinerComp.this.dataManager.getNotificationRouter() .removeObserver( ZoneCombinerComp.this.comboChangeListener); + ZoneCombinerComp.this.asyncExecutor.shutdown(); } }); @@ -954,23 +965,41 @@ public class ZoneCombinerComp extends Composite implements IZoneCombiner { zoneSelector.updateCombos(comboDict); } - public Map loadCombinationsFile(String comboName) { - Map dict = new HashMap(); + private Map loadCombinationsFile(final String comboName) { + List> combolist = Collections.emptyList(); try { - List> combolist = CombinationsFileUtil.init(comboName); + Callable>> loadTask = new Callable>>() { - // reformat combinations into combo dictionary - int group = 1; - for (List zonelist : combolist) { - for (String z : zonelist) { - dict.put(z, group); + @Override + public List> call() throws Exception { + return CombinationsFileUtil.init(comboName); } - group += 1; + }; + + Future>> taskResult = asyncExecutor + .submit(loadTask); + combolist = taskResult.get(); + } catch (ExecutionException e) { + statusHandler.handle(Priority.SIGNIFICANT, + "Could not load combinations file " + comboName, e); + return Collections.emptyMap(); + } catch (InterruptedException | RejectedExecutionException e) { + /* + * We should only ever fall into this block if the Composite is + * disposing and the ExecutorService has been shutdown. Probably not + * worth logging. + */ + return Collections.emptyMap(); + } + + Map dict = new HashMap(); + // reformat combinations into combo dictionary + int group = 1; + for (List zonelist : combolist) { + for (String z : zonelist) { + dict.put(z, group); } - } catch (GfeException e) { - statusHandler.handle(Priority.SIGNIFICANT, e.getLocalizedMessage(), - e); - return new HashMap(); + group += 1; } currentComboFile = comboName; diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java index a08b44045a..911b63c269 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java @@ -21,6 +21,7 @@ package com.raytheon.viz.gfe.textformatter; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -44,6 +45,7 @@ import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.uf.common.localization.LocalizationFile; import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.SaveableOutputStream; import com.raytheon.uf.common.localization.exception.LocalizationException; import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; import com.raytheon.uf.common.python.PyUtil; @@ -73,8 +75,9 @@ import com.raytheon.viz.gfe.textformatter.CombinationsFileUtil.ComboData.Entry; * Feb 05, 2014 #2591 randerso Forced retrieval of combinations file * Implemented retry on error * Aug 27, 2014 #3561 randerso Yet another attempt to fix combinations file updating - * Sep 08, 2104 #3592 randerso Changed to use only list site level files as all + * Sep 08, 2014 #3592 randerso Changed to use only list site level files as all * combo files are saved to the site level + * Oct 07, 2015 #4695 dgilling Code cleanup to remove compile warnings. * * * @@ -166,12 +169,13 @@ public class CombinationsFileUtil { } public static void saveComboData(String id, Map combos) - throws LocalizationException, SerializationException { + throws LocalizationException, SerializationException, IOException { LocalizationFile lf = idToFile(id); - File file = lf.getFile(false); - ComboData comboData = new ComboData(combos); - jaxb.marshalToXmlFile(comboData, file.getPath()); - lf.save(); + try (SaveableOutputStream out = lf.openOutputStream()) { + ComboData comboData = new ComboData(combos); + jaxb.marshalToStream(comboData, out); + out.save(); + } } public static void deleteComboData(String id) @@ -205,18 +209,19 @@ public class CombinationsFileUtil { } public static Map loadComboData(String id) - throws SerializationException { + throws SerializationException, IOException, LocalizationException { LocalizationFile lf = idToFile(id); - File file = lf.getFile(); - ComboData comboData = jaxb.unmarshalFromXmlFile(file); + try (InputStream in = lf.openInputStream()) { + ComboData comboData = (ComboData) jaxb.unmarshalFromInputStream(in); - Map comboDict = new HashMap( - comboData.combos.size()); - for (Entry entry : comboData.combos) { - comboDict.put(entry.zone, entry.group); + Map comboDict = new HashMap( + comboData.combos.size()); + for (Entry entry : comboData.combos) { + comboDict.put(entry.zone, entry.group); + } + + return comboDict; } - - return comboDict; } @SuppressWarnings("unchecked") @@ -262,15 +267,12 @@ public class CombinationsFileUtil { List> combos = null; HashMap map = new HashMap(); map.put("comboName", comboName); - PythonScript python = null; for (int retryCount = 0; retryCount < MAX_TRIES; retryCount++) { - try { - python = new PythonScript(scriptPath, - PyUtil.buildJepIncludePath( - GfePyIncludeUtil.getCombinationsIncludePath(), - GfePyIncludeUtil.getCommonPythonIncludePath()), - CombinationsFileUtil.class.getClassLoader()); - + try (PythonScript python = new PythonScript(scriptPath, + PyUtil.buildJepIncludePath( + GfePyIncludeUtil.getCombinationsIncludePath(), + GfePyIncludeUtil.getCommonPythonIncludePath()), + CombinationsFileUtil.class.getClassLoader())) { Object com = python.execute("getCombinations", map); combos = (List>) com; @@ -292,10 +294,6 @@ public class CombinationsFileUtil { throw new GfeException("Error loading combinations file: " + comboName, e); } - } finally { - if (python != null) { - python.dispose(); - } } } return combos;