diff --git a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolBaseData.xml b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolBaseData.xml index 411e9a2128..2d5266b6f2 100644 --- a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolBaseData.xml +++ b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolBaseData.xml @@ -60,9 +60,9 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -230,9 +94,9 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -352,9 +148,9 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -454,9 +182,9 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -639,8 +231,7 @@ - - + @@ -655,58 +246,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -718,8 +257,7 @@ - - + @@ -734,58 +272,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -812,8 +298,7 @@ - - + @@ -828,58 +313,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -891,8 +324,7 @@ - - + @@ -907,110 +339,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolFourPanelZHCML.xml b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolFourPanelZHCML.xml index 9183ec178d..6250e381c8 100644 --- a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolFourPanelZHCML.xml +++ b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolFourPanelZHCML.xml @@ -6,10 +6,17 @@ Contractor_Address:_____6825_Pine_Street,_Suite_340 ________________________Mail_Stop_B8 ________________________Omaha,_NE_68106 ________________________402.291.0100 See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for further_licensing_information. --> - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -362,8 +165,7 @@ - - + @@ -378,116 +180,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -502,58 +199,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -605,8 +250,7 @@ - - + @@ -621,116 +265,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + > @@ -745,58 +284,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -848,8 +335,7 @@ - - + @@ -864,116 +350,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -988,58 +369,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolHCA.xml b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolHCA.xml index 4f30e8980a..8f78c5c530 100644 --- a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolHCA.xml +++ b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolHCA.xml @@ -48,9 +48,8 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -214,9 +85,8 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -321,8 +127,7 @@ - - + @@ -337,58 +142,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -400,8 +153,7 @@ - - + @@ -416,58 +168,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -512,9 +212,8 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolPrecipAnalysis.xml b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolPrecipAnalysis.xml index 615d7c65cc..0bc4f6d2b0 100644 --- a/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolPrecipAnalysis.xml +++ b/cave/build/static/common/cave/etc/bundles/DefaultRadarDualPolPrecipAnalysis.xml @@ -191,9 +191,9 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java index 530ccb3231..1f1bf5ad41 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java @@ -19,8 +19,10 @@ **/ package com.raytheon.uf.viz.core; +import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.TreeSet; import org.apache.commons.beanutils.ConstructorUtils; @@ -56,7 +58,7 @@ public class RecordFactory { private static RecordFactory instance = new RecordFactory(); /** Map containing the pluginName/Record class pairs */ - private Map> defMap; + private Map> defMap = new HashMap>(); public static final String WILDCARD = "%"; @@ -82,36 +84,39 @@ public class RecordFactory { } @SuppressWarnings("unchecked") - private synchronized void loadDefMap() throws VizException { - if (defMap == null) { - GetPluginRecordMapRequest req = new GetPluginRecordMapRequest(); - Map pluginRecordMap = (Map) ThriftClient - .sendRequest(req); - Map> newDefMap = new HashMap>( - pluginRecordMap.size()); - for (Map.Entry entry : pluginRecordMap.entrySet()) { - String pluginName = entry.getKey(); - String record = entry.getValue(); - if (record != null) { - try { - Class clazz = (Class) Class - .forName(record); - newDefMap.put(pluginName, clazz); - } catch (Exception e) { - statusHandler.handle(Priority.DEBUG, - "Can't find record class for " + pluginName - + " plugin", e); - System.out - .println("DEBUG: Can't find record class for " - + pluginName + " plugin - alerts on " - + pluginName + " data will be ignored"); - } + private void loadDefMap() throws VizException { + GetPluginRecordMapRequest req = new GetPluginRecordMapRequest(); + Map pluginRecordMap = (Map) ThriftClient + .sendRequest(req); + for (Map.Entry entry : pluginRecordMap.entrySet()) { + String pluginName = entry.getKey(); + String record = entry.getValue(); + if (record != null) { + try { + Class clazz = (Class) Class + .forName(record); + defMap.put(pluginName, clazz); + } catch (Exception e) { + statusHandler.handle(Priority.DEBUG, + "Can't find record class for " + pluginName + + " plugin", e); + System.out.println("DEBUG: Can't find record class for " + + pluginName + " plugin - alerts on " + pluginName + + " data will be ignored"); } } - defMap = newDefMap; } } + /** + * Returns a collection of all supported plugins + * + * @return + */ + public Collection getSupportedPlugins() { + return new TreeSet(defMap.keySet()); + } + /** * Creates a map of the fields and values that compose a given dataURI * @@ -123,7 +128,6 @@ public class RecordFactory { */ public Map loadMapFromUri(String dataURI) throws VizException { - // If no dataURI return if (dataURI == null) { return null; @@ -181,10 +185,10 @@ public class RecordFactory { */ public Class getPluginClass(String pluginName) throws VizException { - if (defMap == null) { - loadDefMap(); + Class retVal = null; + if (defMap != null) { + retVal = defMap.get(pluginName); } - Class retVal = defMap.get(pluginName); if (retVal == null) { throw new NoPluginException("Can't find record class for " + pluginName + " plugin"); diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/drawables/AbstractDescriptor.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/drawables/AbstractDescriptor.java index ab75b65d5f..307534ba69 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/drawables/AbstractDescriptor.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/drawables/AbstractDescriptor.java @@ -578,6 +578,8 @@ public abstract class AbstractDescriptor extends ResourceGroup implements } } synchronized (timeManager) { + DataTime[] oldTimes = timeManager.frames; + int oldIdx = this.frameIndex; if (info.setFrames) { if (info.frameTimes != null) { DataTime[] newTimes = Arrays.copyOf(info.frameTimes, @@ -594,6 +596,14 @@ public abstract class AbstractDescriptor extends ResourceGroup implements timeMatchingMap = new ConcurrentHashMap, DataTime[]>( info.timeMap); } + FramesInfo currInfo = getFramesInfo(); + FramesInfo oldInfo = new FramesInfo(oldTimes, oldIdx); + DataTime oldTime = oldInfo.getCurrentFrame(); + DataTime currTime = currInfo.getCurrentFrame(); + if ((oldTime != null && oldTime.equals(currTime) == false) + || (currTime != null && currTime.equals(oldTime) == false)) { + notifyFrameChanged(oldTime, currTime); + } } } @@ -624,20 +634,8 @@ public abstract class AbstractDescriptor extends ResourceGroup implements * @param frame */ private void setFrameInternal(int frame) { - FramesInfo currInfo = getFramesInfo(); - int frameIndex = currInfo.frameIndex; if (frame != frameIndex) { - DataTime[] times = currInfo.frameTimes; - DataTime oldTime = null, newTime = null; - // Get the old and new time - if (times != null && frameIndex >= 0 && frameIndex < times.length) { - oldTime = times[frameIndex]; - } - if (times != null && frame >= 0 && frame < times.length) { - newTime = times[frame]; - } this.frameIndex = frame; - notifyFrameChanged(oldTime, newTime); } } diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java index d4962390be..cb22cd4fc8 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java @@ -250,7 +250,7 @@ public class CAVELocalizationAdapter implements ILocalizationAdapter { return true; } catch (FileNotFoundException e) { throw new LocalizationOpFailedException( - "Error saving file, does not exist"); + "Error saving, file does not exist"); } finally { // Make sure to close input stream if (in != null) { diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/LocalizationManager.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/LocalizationManager.java index 43ca8f3a26..ba76881380 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/LocalizationManager.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/LocalizationManager.java @@ -777,7 +777,7 @@ public class LocalizationManager implements IPropertyChangeListener { } } catch (VizException e) { throw new LocalizationOpFailedException( - "Error storing file contents to server: " + "Error uploading file contents to localization server: " + e.getLocalizedMessage(), e); } diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java index 7baa0495bd..e3090c49b3 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java @@ -275,6 +275,20 @@ public abstract class AbstractRequestableResourceData extends Validate.isTrue(updateData instanceof Object[], "Update expected Object[]"); + if (updateData instanceof PluginDataObject[]) { + for (PluginDataObject pdo : (PluginDataObject[]) updateData) { + DataTime time = pdo.getDataTime(); + if (binOffset != null) { + time = binOffset.getNormalizedTime(time); + } + synchronized (cachedAvailableTimes) { + if (!cachedAvailableTimes.contains(time)) { + cachedAvailableTimes.add(time); + } + } + } + } + this.fireChangeListeners(ChangeType.DATA_UPDATE, updateData); } @@ -669,7 +683,6 @@ public abstract class AbstractRequestableResourceData extends int result = 1; result = prime * result + ((binOffset == null) ? 0 : binOffset.hashCode()); - result = prime * result + (isUpdatingOnMetadataOnly ? 1231 : 1237); result = prime * result + ((metadataMap == null) ? 0 : metadataMap.hashCode()); result = prime * result @@ -710,10 +723,6 @@ public abstract class AbstractRequestableResourceData extends return false; } - if (isUpdatingOnMetadataOnly != other.isUpdatingOnMetadataOnly) { - return false; - } - if (!isObjectsEqual(metadataMap, other.metadataMap)) { return false; } diff --git a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/D2DTimeMatcher.java b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/D2DTimeMatcher.java index b834e1d02b..b92da6d491 100644 --- a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/D2DTimeMatcher.java +++ b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/D2DTimeMatcher.java @@ -828,19 +828,23 @@ public class D2DTimeMatcher extends AbstractTimeMatcher { */ public void changeTimeMatchBasis(AbstractVizResource resource) { if (timeMatchBasis != resource) { - TimeMatchingConfiguration config = getConfiguration(resource - .getLoadProperties()); - TimeCache timeCache = getTimeCache(resource); if (timeMatchBasis != null) { + TimeMatchingConfiguration config = getConfiguration(timeMatchBasis + .getLoadProperties()); config.setTimeMatchBasis(false); + TimeCache timeCache = getTimeCache(timeMatchBasis); timeCache.setTimes(null, null); timeMatchBasis .unregisterListener(timeMatchBasisDisposeListener); } timeMatchBasis = resource; + if (timeMatchBasis != null) { + TimeMatchingConfiguration config = getConfiguration(timeMatchBasis + .getLoadProperties()); config.setTimeMatchBasis(true); + TimeCache timeCache = getTimeCache(timeMatchBasis); timeCache.setTimes(null, null); timeMatchBasis.registerListener(timeMatchBasisDisposeListener); } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/HistoryListDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/HistoryListDlg.java index eb1edf11b5..50cdc4fbc8 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/HistoryListDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/HistoryListDlg.java @@ -47,8 +47,6 @@ import com.raytheon.viz.ui.HistoryList; import com.raytheon.viz.ui.HistoryList.IHistoryListener; import com.raytheon.viz.ui.UiPlugin; import com.raytheon.viz.ui.UiUtil; -import com.raytheon.viz.ui.actions.LoadSerializedXml; -import com.raytheon.viz.ui.actions.SaveBundle; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; import com.raytheon.viz.ui.dialogs.ICloseCallback; import com.raytheon.viz.ui.editor.AbstractEditor; @@ -331,28 +329,22 @@ public class HistoryListDlg extends CaveSWTDialog { } private void loadAlterBundle(Bundle b) { - try { - String editorName = null; + String editorName = null; - if (b.getDisplays().length > 0) { - editorName = DescriptorMap.getEditorId(b.getDisplays()[0] - .getDescriptor().getClass().getName()); - } - - AbstractEditor editor = UiUtil.createOrOpenEditor(editorName, - b.getDisplays()); - - for (IDisplayPane pane : editor.getDisplayPanes()) { - pane.getRenderableDisplay().getDescriptor().getResourceList() - .clear(); - } - - LoadSerializedXml.loadTo(editor, b); - HistoryList.getInstance().addBundle(b); - } catch (VizException e) { - final String err = "Error loading bundle"; - statusHandler.handle(Priority.PROBLEM, err, e); + if (b.getDisplays().length > 0) { + editorName = DescriptorMap.getEditorId(b.getDisplays()[0] + .getDescriptor().getClass().getName()); } + + AbstractEditor editor = UiUtil.createOrOpenEditor(editorName, + b.getDisplays()); + + for (IDisplayPane pane : editor.getDisplayPanes()) { + pane.getRenderableDisplay().getDescriptor().getResourceList() + .clear(); + } + + ProcedureLoadJob.getInstance().enqueue(b, editor); } /** @@ -378,10 +370,7 @@ public class HistoryListDlg extends CaveSWTDialog { return; } - LoadSerializedXml.loadTo(editor, b); - Bundle currBundle = SaveBundle.extractCurrentBundle(); - - HistoryList.getInstance().refreshLatestBundle(currBundle); + ProcedureLoadJob.getInstance().enqueue(b, editor); } catch (VizException e) { statusHandler.handle(Priority.SIGNIFICANT, "Error loading bundle", e); diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureLoadJob.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureLoadJob.java index 293636dae4..f4e9e2af89 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureLoadJob.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureLoadJob.java @@ -28,12 +28,8 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.procedures.Bundle; -import com.raytheon.viz.ui.actions.LoadSerializedXml; +import com.raytheon.viz.ui.BundleLoader; import com.raytheon.viz.ui.editor.AbstractEditor; /** @@ -54,8 +50,6 @@ import com.raytheon.viz.ui.editor.AbstractEditor; */ public class ProcedureLoadJob { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(ProcedureLoadJob.class); private static final ProcedureLoadJob instance = new ProcedureLoadJob(); @@ -79,12 +73,7 @@ public class ProcedureLoadJob { AbstractEditor editor = entry.getKey(); Bundle b = entry.getValue(); - try { - LoadSerializedXml.loadTo(editor, b); - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, - "Error loading bundle", e); - } + new BundleLoader(editor, b).run(); } } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java index 8326b0ff29..de0c3c2f85 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java @@ -63,10 +63,10 @@ import com.raytheon.uf.viz.d2d.core.legend.D2DLegendResource.LegendMode; import com.raytheon.uf.viz.d2d.core.map.MapScales; import com.raytheon.uf.viz.d2d.core.map.MapScales.MapScale; import com.raytheon.uf.viz.d2d.core.map.MapScales.PartId; +import com.raytheon.viz.ui.BundleLoader; import com.raytheon.viz.ui.EditorUtil; import com.raytheon.viz.ui.HistoryList; import com.raytheon.viz.ui.UiUtil; -import com.raytheon.viz.ui.actions.LoadSerializedXml; import com.raytheon.viz.ui.color.BackgroundColor; import com.raytheon.viz.ui.color.IBackgroundColorChangedListener; import com.raytheon.viz.ui.editor.AbstractEditor; @@ -207,12 +207,7 @@ public class SideView extends ViewPart implements IMultiPaneEditor, } if (bundleToLoad != null) { - try { - LoadSerializedXml.loadTo(this, bundleToLoad); - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, - "Error loading bundle view", e); - } + new BundleLoader(this, bundleToLoad).run(); } } @@ -604,12 +599,12 @@ public class SideView extends ViewPart implements IMultiPaneEditor, if (editableResource != null) { EditableManager.makeEditable(editableResource, false); } - - this.editableResource = editableResource; + + this.editableResource = editableResource; if (this.editableResource != null) { EditableManager.makeEditable(this.editableResource, true); } - + theEditor.getBackgroundColor().setColor(BGColorMode.EDITOR, myRenderables[0].getBackgroundColor()); diff --git a/cave/com.raytheon.uf.viz.datadelivery.feature/feature.xml b/cave/com.raytheon.uf.viz.datadelivery.feature/feature.xml index d98a45b0ea..0cbd7f3762 100644 --- a/cave/com.raytheon.uf.viz.datadelivery.feature/feature.xml +++ b/cave/com.raytheon.uf.viz.datadelivery.feature/feature.xml @@ -99,6 +99,13 @@ version="0.0.0" unpack="false"/> + + + class="com.raytheon.uf.common.datadelivery.service.SendToServerSubscriptionNotificationService" /> + + @@ -28,6 +31,7 @@ + * @@ -886,6 +887,7 @@ public class BandwidthCanvasComp extends Composite implements IDialogClosed, MenuItem viewSubs = new MenuItem(m, SWT.NONE); viewSubs.setText("View Selected Subscriptions..."); + viewSubs.setEnabled(imageMgr.hasSubscriptionNameChecked()); viewSubs.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/BandwidthImageMgr.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/BandwidthImageMgr.java index dd24fb4e81..70a2b068ea 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/BandwidthImageMgr.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/BandwidthImageMgr.java @@ -20,6 +20,7 @@ package com.raytheon.uf.viz.datadelivery.bandwidth.ui; import java.util.Collection; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; @@ -30,7 +31,7 @@ import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import com.raytheon.uf.common.datadelivery.bandwidth.data.BandwidthGraphData; -import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionPriority; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; /** * Bandwidth utilization graph image manager. @@ -42,7 +43,9 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionP * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Nov 28, 2012 1269 lvenable Initial creation - * Dec 13, 2012 1269 lvenable Fixes and updates. + * Dec 13, 2012 1269 lvenable Fixes and updates. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum on subscriptions. + * Jan 28, 2013 1529 djohnson Add hasSubscriptionNameChecked(). * * * @@ -137,10 +140,11 @@ public class BandwidthImageMgr implements IGraphOptions { private void init(Composite parentComp, BandwidthGraphData graphData, Map canvasSettingsMap) { - priorityColorMap = new HashMap(); - for (SubscriptionPriority priority : SubscriptionPriority.values()) { - priorityColorMap.put(priority, priority.getColor()); - } + priorityColorMap = new EnumMap( + SubscriptionPriority.class); + priorityColorMap.put(SubscriptionPriority.LOW, new RGB(6, 122, 255)); + priorityColorMap.put(SubscriptionPriority.NORMAL, new RGB(0, 255, 0)); + priorityColorMap.put(SubscriptionPriority.HIGH, new RGB(255, 0, 0)); canvasImgMap = new HashMap(); populateCanvasMap(parentComp, graphData, canvasSettingsMap); @@ -488,4 +492,13 @@ public class BandwidthImageMgr implements IGraphOptions { regenerateImage(CanvasImages.X_HEADER); } -} \ No newline at end of file + + /** + * Check whether there is a checked subscription name. + * + * @return true if at least one subscription name is checked + */ + public boolean hasSubscriptionNameChecked() { + return checkMap.containsValue(Boolean.TRUE); + } +} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/GraphImage.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/GraphImage.java index 463b077dcb..7b7e44fa96 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/GraphImage.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/GraphImage.java @@ -34,9 +34,9 @@ import org.eclipse.swt.widgets.Composite; import com.raytheon.uf.common.datadelivery.bandwidth.data.BandwidthGraphData; import com.raytheon.uf.common.datadelivery.bandwidth.data.TimeWindowData; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.viz.datadelivery.bandwidth.ui.BandwidthImageMgr.SortBy; -import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionPriority; /** * The graph image class. @@ -51,6 +51,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionP * Dec 13, 2012 1269 lvenable Fixes and updates. * Jan 07, 2013 1451 djohnson Use TimeUtil.newGmtCalendar(). * Jan 04, 2013 1420 mpduff Change default priority to normal priority. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum, remove incorrect use of ordinal values. * * * @@ -171,20 +172,17 @@ public class GraphImage extends AbstractCanvasImage { for (String subName : subscriptionList) { if (imageMgr.isColorByPriority()) { - if (graphData.getPriority(subName) == SubscriptionPriority.NORMAL - .ordinal()) { + if (graphData.getPriority(subName) == SubscriptionPriority.NORMAL) { c = new Color( display, imageMgr.getPriorityColor(SubscriptionPriority.NORMAL)); gc.setBackground(c); - } else if (graphData.getPriority(subName) == SubscriptionPriority.HIGH - .ordinal()) { + } else if (graphData.getPriority(subName) == SubscriptionPriority.HIGH) { c = new Color( display, imageMgr.getPriorityColor(SubscriptionPriority.HIGH)); gc.setBackground(c); - } else if (graphData.getPriority(subName) == SubscriptionPriority.LOW - .ordinal()) { + } else if (graphData.getPriority(subName) == SubscriptionPriority.LOW) { c = new Color(display, imageMgr.getPriorityColor(SubscriptionPriority.LOW)); gc.setBackground(c); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/IGraphOptions.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/IGraphOptions.java index d5d16946a2..aaf84b96d3 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/IGraphOptions.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/IGraphOptions.java @@ -21,7 +21,7 @@ package com.raytheon.uf.viz.datadelivery.bandwidth.ui; import org.eclipse.swt.graphics.RGB; -import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionPriority; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; /** * TODO Add Description diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/XHeaderImage.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/XHeaderImage.java index 912b8c2c5c..6e2b3d7156 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/XHeaderImage.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/bandwidth/ui/XHeaderImage.java @@ -32,7 +32,7 @@ import org.eclipse.swt.widgets.ColorDialog; import org.eclipse.swt.widgets.Composite; import com.raytheon.uf.common.datadelivery.bandwidth.data.BandwidthGraphData; -import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionPriority; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; /** * Header image for X axis. @@ -45,6 +45,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionP * ------------ ---------- ----------- -------------------------- * Nov 28, 2012 1269 lvenable Initial creation. * Dec 13, 2012 1269 lvenable Fixes and updates. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -75,7 +76,7 @@ public class XHeaderImage extends AbstractCanvasImage { private final String sortBy = "Sort by: "; /** Map of rectangles and subscription priorities. */ - private Map rectPriMap; + private final Map rectPriMap; /** * Constructor. diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java index d6c0ebe66e..69355e61c1 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java @@ -113,6 +113,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes. * Dec 12, 2012 1391 bgonzale Added job for dataset retrieval. * Jan 08, 2012 1436 bgonzale Fixed area text box display update check. + * Jan 14, 2012 1437 bgonzale Clear filters when creating a new configuration. * * * @@ -860,6 +861,7 @@ public class DataBrowserDlg extends CaveSWTDialog implements IDataTableUpdate, return; } + xml = new FilterSettingsXML(); setText(WINDOW_TITLE); // Clear the area. @@ -871,6 +873,8 @@ public class DataBrowserDlg extends CaveSWTDialog implements IDataTableUpdate, dataTypesDualList.clearSelection(); // Clear the filters. + updateFilters(); + filterExpandBar.updateFilters(dataTypesDualList.getSelectedListItems(), envelope); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java index dfeae92a25..180afac3f5 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java @@ -20,6 +20,8 @@ package com.raytheon.uf.viz.datadelivery.common.ui; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; @@ -28,7 +30,7 @@ import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; -import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionPriority; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; /** * This is the priority group information composite. This class is intended to @@ -43,6 +45,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionP * Jun 27, 2012 702 jpiatt Initial creation. * Aug 21, 2012 712 mpduff Default to Default, and allow for setting the combo box. * Jan 04, 2013 1420 mpduff Add latency. + * Jan 25, 2013 1528 djohnson Use priority enum instead of raw integers. * * * @@ -60,7 +63,7 @@ public class PriorityComp extends Composite { private final int latency; /** The priority value */ - private final int priority; + private SubscriptionPriority priority; /** * Constructor. @@ -70,10 +73,11 @@ public class PriorityComp extends Composite { * @param latency * @param priority */ - public PriorityComp(Composite parent, int latency, int priority) { + public PriorityComp(Composite parent, int latency, + SubscriptionPriority priority) { super(parent, SWT.NONE); this.latency = latency; - this.priority = priority - 1; + this.priority = priority; init(); } @@ -127,9 +131,16 @@ public class PriorityComp extends Composite { gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); priorityCombo = new Combo(priorityComp, SWT.READ_ONLY); priorityCombo.setItems(priorities); - priorityCombo.select(this.priority); priorityCombo.setLayoutData(gd); priorityCombo.setToolTipText("Select a priority"); + priorityCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + priority = SubscriptionPriority.fromPriorityName(priorityCombo + .getItem(priorityCombo.getSelectionIndex())); + } + }); + setPriority(priority); Composite latencyComp = new Composite(subPriorityGroup, SWT.NONE); gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); @@ -153,8 +164,8 @@ public class PriorityComp extends Composite { * * @return priority */ - public int getPriorityIndex() { - return priorityCombo.getSelectionIndex(); + public SubscriptionPriority getPriority() { + return priority; } /** @@ -162,10 +173,9 @@ public class PriorityComp extends Composite { * * @param index */ - public void setPriorityIndex(int index) { - if (index <= priorityCombo.getItemCount()) { - priorityCombo.select(index); - } + public void setPriority(SubscriptionPriority priority) { + priorityCombo.select(priorityCombo.indexOf(priority.getPriorityName())); + this.priority = priority; } /** diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java index a05d1b40f0..4c3f0b995c 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java @@ -413,6 +413,7 @@ public class UserSelectComp extends Composite implements IUpdate, IDisplay, u.setEnvelope(groupDefinition.getEnvelope()); u.setNumFcstHours(subscription.getTime() .getSelectedTimeIndices().size()); + u.setNumEnsembleMembers(subscription.getEnsemble()); u.determineNumberRequestedGrids(subscription.getParameter()); Coverage cov = new GriddedCoverage(); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java index 2342df35d2..602302293e 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java @@ -95,6 +95,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * Oct 22, 2012 1284 mpduff Code Cleanup. * Dec 03, 2012 1285 bgonzale Added implementation of the tableLock method. * Update title bar text when paused. + * Jan 22, 2013 1520 mpduff Change delete menus to hide. * * * @@ -272,7 +273,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, MenuItem setDefaultMI = new MenuItem(fileMenu, SWT.NONE); lockableMenuItems.add(setDefaultMI); - setDefaultMI.setText("&Set as Default"); + setDefaultMI.setText("Set as Default"); setDefaultMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -282,7 +283,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, MenuItem loadConfigMI = new MenuItem(fileMenu, SWT.NONE); lockableMenuItems.add(loadConfigMI); - loadConfigMI.setText("&Load Configuration..."); + loadConfigMI.setText("Load Configuration..."); loadConfigMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -298,7 +299,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, MenuItem saveConfigMI = new MenuItem(fileMenu, SWT.NONE); lockableMenuItems.add(saveConfigMI); - saveConfigMI.setText("&Save Configuration"); + saveConfigMI.setText("Save Configuration"); saveConfigMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -308,7 +309,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, MenuItem saveConfigAsMI = new MenuItem(fileMenu, SWT.NONE); lockableMenuItems.add(saveConfigAsMI); - saveConfigAsMI.setText("&Save Configuration As..."); + saveConfigAsMI.setText("Save Configuration As..."); saveConfigAsMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -318,7 +319,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, MenuItem deleteConfigMI = new MenuItem(fileMenu, SWT.NONE); lockableMenuItems.add(deleteConfigMI); - deleteConfigMI.setText("&Delete Configuration..."); + deleteConfigMI.setText("Delete Configuration..."); deleteConfigMI.addSelectionListener(new SelectionAdapter() { @Override @@ -330,7 +331,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, new MenuItem(fileMenu, SWT.SEPARATOR); MenuItem exitMI = new MenuItem(fileMenu, SWT.NONE); - exitMI.setText("&Exit"); + exitMI.setText("Exit"); exitMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -348,7 +349,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, // Find Menu MenuItem findMI = new MenuItem(editMenu, SWT.CASCADE); lockableMenuItems.add(findMI); - findMI.setText("&Find..."); + findMI.setText("Find..."); findMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -356,10 +357,10 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, } }); - MenuItem delPriorityMI = new MenuItem(editMenu, SWT.CASCADE); - lockableMenuItems.add(delPriorityMI); - delPriorityMI.setText("&Delete by Priority"); - delPriorityMI.addSelectionListener(new SelectionAdapter() { + MenuItem hidePriorityMI = new MenuItem(editMenu, SWT.CASCADE); + lockableMenuItems.add(hidePriorityMI); + hidePriorityMI.setText("Hide by Priority"); + hidePriorityMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -367,14 +368,14 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, }); Menu subMenu = new Menu(menuBar); - delPriorityMI.setMenu(subMenu); + hidePriorityMI.setMenu(subMenu); createPriorityMenus(subMenu); - MenuItem deleteOlderMI = new MenuItem(editMenu, SWT.NONE); - lockableMenuItems.add(deleteOlderMI); - deleteOlderMI.setText("&Delete Older Than Selected"); - deleteOlderMI.addSelectionListener(new SelectionAdapter() { + MenuItem hideOlderMI = new MenuItem(editMenu, SWT.NONE); + lockableMenuItems.add(hideOlderMI); + hideOlderMI.setText("Hide Older Than Selected"); + hideOlderMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { tableComp.handleDeleteOlderThan(); @@ -382,10 +383,10 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, }); - MenuItem deleteMI = new MenuItem(editMenu, SWT.NONE); - lockableMenuItems.add(deleteMI); - deleteMI.setText("&Delete Notification(s)"); - deleteMI.addSelectionListener(new SelectionAdapter() { + MenuItem hideMI = new MenuItem(editMenu, SWT.NONE); + lockableMenuItems.add(hideMI); + hideMI.setText("Hide Notification(s)"); + hideMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { tableComp.handleDeleteNotification(); @@ -401,7 +402,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, MenuItem configureMI = new MenuItem(settingsMenu, SWT.NONE); lockableMenuItems.add(configureMI); - configureMI.setText("&Configure Table..."); + configureMI.setText("Configure Table..."); configureMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -411,7 +412,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, MenuItem filterMI = new MenuItem(settingsMenu, SWT.NONE); lockableMenuItems.add(filterMI); - filterMI.setText("&Filter Table..."); + filterMI.setText("Filter Table..."); filterMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -420,7 +421,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, }); tooltipMI = new MenuItem(settingsMenu, SWT.CHECK); - tooltipMI.setText("&Tooltips"); + tooltipMI.setText("Tooltips"); tooltipMI.setSelection(false); tooltipMI.addSelectionListener(new SelectionAdapter() { @Override @@ -438,7 +439,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, helpMenuItem.setMenu(helpMenu); MenuItem helpNotTableMI = new MenuItem(helpMenu, SWT.NONE); - helpNotTableMI.setText("&About Notification Center..."); + helpNotTableMI.setText("About Notification Center..."); helpNotTableMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationTableComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationTableComp.java index 20373b8bdc..2be48e7781 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationTableComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationTableComp.java @@ -75,7 +75,7 @@ import com.raytheon.uf.viz.datadelivery.utils.NotificationHandler; * Sep 06, 2012 687 mpduff Call the table selection method of the ITableChanged interface. * Oct 22, 2012 1284 mpduff Fix the start/end index for pagination of new records, code cleanup. * Nov 29, 2012 1285 bgonzale Added a refresh pause button to the Notification Center Dialog. - * + * Jan 22, 2013 1520 mpduff Update javadoc. * * * @author lvenable @@ -197,12 +197,12 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Constructor. - * + * * Note: For the super class we are passing in a false for the notification * flag. This is turned off because the notification dialog is using the * NotificationHandler and it contains the necessary code that needs to be * executed. - * + * * @param parent * @param tableConfig * @param callback @@ -287,6 +287,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { + " not refresh, re-sort, or allow user modification" + " until unchecked."); pauseButton.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { boolean isLocked = pauseButton.getSelection(); @@ -320,7 +321,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the entire table list. - * + * * @return TableDataManager obj */ public TableDataManager getMasterTableList() { @@ -329,7 +330,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the table list with filters applied. - * + * * @return TableDataManager obj */ public TableDataManager getFilteredTableList() { @@ -338,7 +339,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the table list for display. - * + * * @return TableDataManager obj */ public ArrayList getVisibleTableList() { @@ -347,7 +348,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the rows of data to display. - * + * * @return list of Notification Row Data objects */ private ArrayList getTableRows() { @@ -359,7 +360,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { // Recalculate start/end indices for visible page if (numRows > endIndex && endIndex - startIndex < pageConfig) { - endIndex = startIndex + pageConfig - 1;//numRows -1; + endIndex = startIndex + pageConfig - 1;// numRows -1; if (endIndex - startIndex > pageConfig - 1) { startIndex = ((pageConfig * selectedPage) - (pageConfig - 1)) - 1; } @@ -390,7 +391,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Delete table rows. - * + * * @param deleteRecordIds */ public void deleteTableDataRows(ArrayList deleteRecordIds) { @@ -408,7 +409,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the table obj. - * + * * @return the table obj. */ public Table getTable() { @@ -432,7 +433,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { } /** - * Action taken when deleting a notification. + * Action taken when deleting a notification from view. */ public void handleDeleteNotification() { @@ -472,7 +473,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Action taken when tool tip is selected. - * + * * @param showToolTips * true when tooltips are on */ @@ -612,7 +613,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { } /** - * Action taken when deleted notifications by time. + * Action taken when deleted notifications from view by time. */ public void handleDeleteOlderThan() { @@ -689,8 +690,8 @@ public class NotificationTableComp extends TableComp implements ITableFind { } /** - * Action taken to delete notifications by priority. - * + * Action taken to delete notifications from view by priority. + * * @param priority * priority indicator */ @@ -726,7 +727,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the start index. - * + * * @return start index */ public int getStartIndex() { @@ -735,7 +736,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the end index. - * + * * @return end index */ public int getEndIndex() { @@ -744,7 +745,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the selected index. - * + * * @return selected index */ public int getSelectedIndex() { @@ -753,7 +754,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the table cell text. - * + * * @param name * The column name * @param rd @@ -782,7 +783,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Populate the NotificationRowData objects - * + * * @param notificationRecords * list of notification records */ @@ -857,7 +858,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Pass filter information. - * + * * @param username * user name table data * @param priority @@ -915,11 +916,11 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Pass filter information. - * + * * @param records * Notification record * @return boolean true if passes filter - * + * */ public boolean passesFilter(List records) { for (NotificationRecord record : records) { @@ -933,10 +934,10 @@ public class NotificationTableComp extends TableComp implements ITableFind { /** * Get the column data. - * + * * @param colName * The column name of interest - * + * * @return The populated ColumnXML object */ private ColumnXML getColumnData(String colName) { @@ -1144,7 +1145,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /* * (non-Javadoc) - * + * * @see * com.raytheon.uf.viz.datadelivery.common.ui.TableComp#handleTableMouseClick * (org.eclipse.swt.events.MouseEvent) @@ -1156,7 +1157,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /* * (non-Javadoc) - * + * * @see com.raytheon.uf.viz.datadelivery.common.ui.TableComp# * handleTableSelectionChange(org.eclipse.swt.events.SelectionEvent) */ @@ -1169,7 +1170,7 @@ public class NotificationTableComp extends TableComp implements ITableFind { /* * (non-Javadoc) - * + * * @see com.raytheon.uf.viz.core.notification.INotificationObserver# * notificationArrived * (com.raytheon.uf.viz.core.notification.NotificationMessage[]) diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/services/DataDeliveryServices.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/services/DataDeliveryServices.java index 137df8d822..d872a54231 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/services/DataDeliveryServices.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/services/DataDeliveryServices.java @@ -20,8 +20,9 @@ package com.raytheon.uf.viz.datadelivery.services; import com.raytheon.uf.common.datadelivery.bandwidth.IBandwidthService; +import com.raytheon.uf.common.datadelivery.service.IGroupDefinitionService; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; import com.raytheon.uf.viz.datadelivery.subscription.IPermissionsService; -import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionNotificationService; import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService; /** @@ -55,6 +56,8 @@ public final class DataDeliveryServices { private IPermissionsService permissionsService; + private IGroupDefinitionService groupDefinitionService; + /** * Disabled constructor. */ @@ -147,4 +150,24 @@ public final class DataDeliveryServices { public void setPermissionsService(IPermissionsService permissionsService) { this.permissionsService = permissionsService; } + + /** + * Get the group definition service. + * + * @return the groupDefinitionService + */ + public static IGroupDefinitionService getGroupDefinitionService() { + return INSTANCE.groupDefinitionService; + } + + /** + * Set the group definition service. + * + * @param groupDefinitionService + * the groupDefinitionService to set + */ + public void setGroupDefinitionService( + IGroupDefinitionService groupDefinitionService) { + this.groupDefinitionService = groupDefinitionService; + } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java index 72c8531627..16c3244d72 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java @@ -39,6 +39,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.datadelivery.registry.ebxml.DataSetQuery; import com.raytheon.uf.viz.datadelivery.common.ui.ActivePeriodComp; import com.raytheon.uf.viz.datadelivery.common.ui.DeliveryOptionsComp; @@ -79,6 +80,7 @@ import com.raytheon.viz.ui.presenter.components.ComboBoxConf; * Dec 13, 2012 1391 bgonzale Added cancel/ok selection status. * Jan 02, 2013 1441 djohnson Add isGroupSelected(). * Jan 04, 2013 1420 mpduff Add latency. + * Jan 25, 2013 1528 djohnson Use priority enum instead of raw integers. * * * @@ -195,7 +197,8 @@ public class CreateSubscriptionDlg extends CaveSWTDialog implements // Get latency value SystemRuleManager ruleManager = SystemRuleManager.getInstance(); int latency = ruleManager.getLatency(this.subscription, cycleTimes); - int priority = ruleManager.getPriority(this.subscription, cycleTimes); + SubscriptionPriority priority = ruleManager.getPriority( + this.subscription, cycleTimes); priorityComp = new PriorityComp(mainComp, latency, priority); this.createCycleGroup(); @@ -517,16 +520,16 @@ public class CreateSubscriptionDlg extends CaveSWTDialog implements * {@inheritDoc} */ @Override - public int getPriority() { - return priorityComp.getPriorityIndex(); + public SubscriptionPriority getPriority() { + return priorityComp.getPriority(); } /** * {@inheritDoc} */ @Override - public void setPriority(int i) { - priorityComp.setPriorityIndex(i); + public void setPriority(SubscriptionPriority priority) { + priorityComp.setPriority(priority); } /** @@ -842,14 +845,6 @@ public class CreateSubscriptionDlg extends CaveSWTDialog implements this.subscription = subscription; } - /** - * {@inheritDoc} - */ - @Override - public int getPriorityValue() { - return priorityComp.getPriorityIndex(); - } - /** * {@inheritDoc} */ diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DeleteGroupDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DeleteGroupDlg.java index 51fc1a218b..1b1a40f50a 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DeleteGroupDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DeleteGroupDlg.java @@ -29,12 +29,14 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; +import com.raytheon.uf.common.datadelivery.service.IGroupDefinitionService; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.datadelivery.common.ui.GroupSelectComp; import com.raytheon.uf.viz.datadelivery.common.ui.IGroupAction; +import com.raytheon.uf.viz.datadelivery.services.DataDeliveryServices; import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; @@ -47,7 +49,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 2, 2013 1441 djohnson Initial creation + * Jan 2, 2013 1441 djohnson Initial creation + * Jan 18, 2013 1441 djohnson Use group definition service. * * * @@ -68,6 +71,9 @@ public class DeleteGroupDlg extends CaveSWTDialog { private final IUFStatusHandler statusHandler = UFStatus .getHandler(DeleteGroupDlg.class); + private final IGroupDefinitionService groupService = DataDeliveryServices + .getGroupDefinitionService(); + /** * @param shell * @param groupAction @@ -144,8 +150,11 @@ public class DeleteGroupDlg extends CaveSWTDialog { + groupName + "?")) { try { - DataDeliveryHandlers.getGroupDefinitionHandler() - .deleteByName(groupName); + groupService + .deleteGroupDefinition( + DataDeliveryHandlers + .getGroupDefinitionHandler() + .getByName(groupName)); groupAction.loadGroupNames(); return true; } catch (RegistryHandlerException e) { diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/GroupAddDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/GroupAddDlg.java index c3336c42c2..fa1c062988 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/GroupAddDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/GroupAddDlg.java @@ -34,6 +34,7 @@ import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.datadelivery.registry.GroupDefinition; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/RequestFromServerPermissionsService.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/RequestFromServerPermissionsService.java index 5876cde154..bd3426dc3f 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/RequestFromServerPermissionsService.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/RequestFromServerPermissionsService.java @@ -19,12 +19,14 @@ **/ package com.raytheon.uf.viz.datadelivery.subscription; +import com.raytheon.uf.common.auth.resp.SuccessfulExecution; import com.raytheon.uf.common.auth.user.IUser; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.request.DataDeliveryAuthRequest; +import com.raytheon.uf.common.datadelivery.request.DataDeliveryConstants; import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission; +import com.raytheon.uf.common.serialization.comm.RequestRouter; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.requests.ThriftClient; /** * {@link IPermissionsService} implementation that requests permissions from the @@ -37,6 +39,7 @@ import com.raytheon.uf.viz.core.requests.ThriftClient; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jan 04, 2013 1441 djohnson Initial creation + * Jan 21, 2013 1441 djohnson Use RequestRouter. * * * @@ -93,8 +96,13 @@ public class RequestFromServerPermissionsService implements IPermissionsService */ private DataDeliveryAuthRequest sendAuthorizationRequest( DataDeliveryAuthRequest request) throws VizException { - return (DataDeliveryAuthRequest) ThriftClient - .sendPrivilegedRequest(request); + try { + return (DataDeliveryAuthRequest) ((SuccessfulExecution) RequestRouter + .route(request, DataDeliveryConstants.DATA_DELIVERY_SERVER)) + .getResponse(); + } catch (Exception e) { + throw new VizException(e); + } } /** diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerDlg.java index 773356ec39..d7ce4442f9 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerDlg.java @@ -53,12 +53,12 @@ import com.raytheon.uf.common.auth.user.IUser; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler; import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.registry.handler.RegistryObjectHandlers; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.auth.UserController; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.datadelivery.actions.DataBrowserAction; @@ -112,6 +112,9 @@ import com.raytheon.viz.ui.presenter.IDisplay; * Jan 02, 2013 1441 djohnson Add ability to delete groups. * Jan 03, 2013 1437 bgonzale Moved configuration file management code to SubscriptionManagerConfigDlg * and SubscriptionConfigurationManager. + * Jan 21, 2013 1501 djohnson Only send notification if subscription was actually activated/deactivated, + * remove race condition of GUI thread updating the table after notification. + * Jan 22, 2013 1520 mpduff Removed menu accelerators. * * * @author mpduff @@ -315,7 +318,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements fileMenuItem.setMenu(fileMenu); MenuItem newMI = new MenuItem(fileMenu, SWT.NONE); - newMI.setText("&New Subscription..."); + newMI.setText("New Subscription..."); newMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -324,7 +327,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements }); MenuItem groupMI = new MenuItem(fileMenu, SWT.NONE); - groupMI.setText("&New Group..."); + groupMI.setText("New Group..."); groupMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -356,7 +359,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements new MenuItem(fileMenu, SWT.SEPARATOR); MenuItem exitMI = new MenuItem(fileMenu, SWT.NONE); - exitMI.setText("&Exit"); + exitMI.setText("Exit"); exitMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -374,7 +377,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements settingsMenuItem.setMenu(settingsMenu); MenuItem configureMI = new MenuItem(settingsMenu, SWT.NONE); - configureMI.setText("&Configure Table..."); + configureMI.setText("Configure Table..."); configureMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -383,7 +386,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements }); tooltipMI = new MenuItem(settingsMenu, SWT.CHECK); - tooltipMI.setText("&Tooltips"); + tooltipMI.setText("Tooltips"); tooltipMI.setSelection(false); tooltipMI.addSelectionListener(new SelectionAdapter() { @Override @@ -401,7 +404,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements helpMenuItem.setMenu(helpMenu); MenuItem helpNotTableMI = new MenuItem(helpMenu, SWT.NONE); - helpNotTableMI.setText("&About Subscription Manager..."); + helpNotTableMI.setText("About Subscription Manager..."); helpNotTableMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -421,7 +424,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements editMenuItem.setMenu(editMenu); MenuItem editMI = new MenuItem(editMenu, SWT.NONE); - editMI.setText("&Edit Subscription..."); + editMI.setText("Edit Subscription..."); editMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -430,7 +433,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements }); MenuItem copyMI = new MenuItem(editMenu, SWT.NONE); - copyMI.setText("&Copy Subscription..."); + copyMI.setText("Copy Subscription..."); copyMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -439,7 +442,7 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements }); MenuItem deleteMI = new MenuItem(editMenu, SWT.NONE); - deleteMI.setText("&Delete Subscription"); + deleteMI.setText("Delete Subscription"); deleteMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -589,8 +592,8 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements String msg = user.uniqueId() + " is not authorized to create subscriptions"; try { - if (DataDeliveryServices.getPermissionsService().checkPermission(user, msg, permission) - .isAuthorized()) { + if (DataDeliveryServices.getPermissionsService() + .checkPermission(user, msg, permission).isAuthorized()) { DataBrowserAction action = new DataBrowserAction(); Map params = new HashMap(); ExecutionEvent ee = new ExecutionEvent(null, params, null, null); @@ -620,8 +623,8 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements + permission; try { - if (DataDeliveryServices.getPermissionsService().checkPermission(user, msg, permission) - .isAuthorized()) { + if (DataDeliveryServices.getPermissionsService() + .checkPermission(user, msg, permission).isAuthorized()) { if (create) { if (createGroupDlg == null) { createGroupDlg = new CreateGroupDefinitionDlg( @@ -742,8 +745,8 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements + permission; try { - if (DataDeliveryServices.getPermissionsService().checkPermission(user, msg, permission) - .isAuthorized()) { + if (DataDeliveryServices.getPermissionsService() + .checkPermission(user, msg, permission).isAuthorized()) { String message = null; if (selectionCount > 1) { @@ -829,8 +832,8 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements + " Subscriptions\nPermission: " + permission; try { - if (DataDeliveryServices.getPermissionsService().checkPermission(user, msg, permission) - .isAuthorized()) { + if (DataDeliveryServices.getPermissionsService() + .checkPermission(user, msg, permission).isAuthorized()) { final List updatedList = new ArrayList(); int count = tableComp.getTable().getSelectionCount(); @@ -864,34 +867,23 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements SWT.OK, sub.getName() + " Activated", response.getMessageToDisplay()); } - updatedList.add(sub); - - if (activate) { - subscriptionNotificationService - .sendSubscriptionActivatedNotification( - sub, - username); - - } else { - subscriptionNotificationService - .sendSubscriptionDeactivatedNotification( - sub, username); + if (!response.isAllowFurtherEditing()) { + if (activate) { + subscriptionNotificationService + .sendSubscriptionActivatedNotification( + sub, username); + } else { + subscriptionNotificationService + .sendSubscriptionDeactivatedNotification( + sub, username); + } } } catch (RegistryHandlerException e) { statusHandler.handle(Priority.PROBLEM, "Error processing request.", e); } } - - VizApp.runAsync(new Runnable() { - @Override - public void run() { - if (isDisposed() == false) { - tableComp.updateTable(updatedList); - } - } - }); } } } catch (VizException e) { @@ -1064,10 +1056,12 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements String msg = user.uniqueId() + " is not authorized to access Subscription Approval"; - return DataDeliveryServices.getPermissionsService().checkPermissions(user, msg, - DataDeliveryPermission.SUBSCRIPTION_APPROVE_SITE, - DataDeliveryPermission.SUBSCRIPTION_APPROVE_USER, - DataDeliveryPermission.SUBSCRIPTION_APPROVE_VIEW) + return DataDeliveryServices + .getPermissionsService() + .checkPermissions(user, msg, + DataDeliveryPermission.SUBSCRIPTION_APPROVE_SITE, + DataDeliveryPermission.SUBSCRIPTION_APPROVE_USER, + DataDeliveryPermission.SUBSCRIPTION_APPROVE_VIEW) .isAuthorized(); } catch (VizException e) { statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); @@ -1097,8 +1091,8 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements for (Subscription subscription : subscriptions) { subscriptionNotificationService - .sendDeletedSubscriptionNotification( - subscription, username); + .sendDeletedSubscriptionNotification(subscription, + username); } } catch (RegistryHandlerException e) { exceptions.add(e); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerRowData.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerRowData.java index 81a7724227..e417a43a43 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerRowData.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionManagerRowData.java @@ -46,6 +46,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.TABLE_TYPE; * Aug 10, 2012 1002 mpduff Change dataset size from int to long. * Aug 21, 2012 712 mpduff Make priorities display as 1, 2, 3. * Oct 2, 2012 1103 jpiatt Remove unused methods, update enum, code clean up. + * Jan 25, 2012 1528 djohnson Priorities no longer need incrementing for display. * * * @author mpduff @@ -67,7 +68,7 @@ public class SubscriptionManagerRowData implements ITableData * @@ -357,6 +359,7 @@ public class SubscriptionService implements ISubscriptionService { final ServiceInteraction action = new ServiceInteraction() { @Override public String call() throws RegistryHandlerException { + subscription.setUnscheduled(false); DataDeliveryHandlers.getSubscriptionHandler().update( subscription); return successMessage; @@ -379,6 +382,7 @@ public class SubscriptionService implements ISubscriptionService { @Override public String call() throws RegistryHandlerException { for (Subscription sub : subs) { + sub.setUnscheduled(false); DataDeliveryHandlers.getSubscriptionHandler().update(sub); } return successMessage; @@ -438,6 +442,7 @@ public class SubscriptionService implements ISubscriptionService { subscription).isAuthorized(); try { if (authorized) { + subscription.setUnscheduled(false); DataDeliveryHandlers.getSubscriptionHandler() .update(subscription); } else { diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionTableComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionTableComp.java index 7611ac3fab..35e8503823 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionTableComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SubscriptionTableComp.java @@ -47,12 +47,12 @@ import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import com.raytheon.uf.common.auth.user.IUser; -import com.raytheon.uf.common.datadelivery.event.notification.SubscriptionNotificationResponse; import com.raytheon.uf.common.datadelivery.registry.PendingSubscription; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler; import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission; +import com.raytheon.uf.common.datadelivery.service.SubscriptionNotificationResponse; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.registry.handler.RegistryObjectHandlers; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -100,6 +100,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.TABLE_TYPE; * Dec 03, 2012 1279 mpduff Add ability to populate from a list of subscription names. * Dec 12, 2012 1391 bgonzale Added a job for subscription retrieves. * Jan 07, 2013 1437 bgonzale Added sort column direction updates. + * Jan 28, 2013 1529 djohnson Disable menu items if no subscriptions are selected. * * * @@ -120,7 +121,7 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction { * Subscription action callback that is called when there is a table * selection. */ - private ISubscriptionAction subActionCallback; + private final ISubscriptionAction subActionCallback; /** TableDataManager object. */ private TableDataManager subManagerData; @@ -756,11 +757,14 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction { popupMenu.dispose(); } + final boolean menuItemsEnabled = table.getSelectionIndices().length > 0; + // Detail popup menu popupMenu = new Menu(table); - MenuItem item1 = new MenuItem(popupMenu, SWT.PUSH); - item1.setText("Details... "); - item1.addSelectionListener(new SelectionAdapter() { + MenuItem detailsItem = new MenuItem(popupMenu, SWT.PUSH); + detailsItem.setText("Details... "); + detailsItem.setEnabled(menuItemsEnabled); + detailsItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleDetails(); @@ -770,6 +774,7 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction { if (subType == SubscriptionType.MANAGER) { MenuItem editItem = new MenuItem(popupMenu, SWT.PUSH); editItem.setText("Edit..."); + editItem.setEnabled(menuItemsEnabled); editItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { @@ -780,6 +785,7 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction { // Add the selected row to a subscription group MenuItem groupItem = new MenuItem(popupMenu, SWT.PUSH); groupItem.setText("Add to Group..."); + groupItem.setEnabled(menuItemsEnabled); groupItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubApprovalTableComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubApprovalTableComp.java index a30fca28e5..20b78e220a 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubApprovalTableComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubApprovalTableComp.java @@ -33,14 +33,14 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; -import com.raytheon.uf.common.datadelivery.event.notification.ApprovedPendingSubscriptionNotificationResponse; -import com.raytheon.uf.common.datadelivery.event.notification.BaseSubscriptionNotificationResponse; -import com.raytheon.uf.common.datadelivery.event.notification.DeniedPendingSubscriptionNotificationResponse; -import com.raytheon.uf.common.datadelivery.event.notification.PendingSubscriptionNotificationResponse; import com.raytheon.uf.common.datadelivery.registry.InitialPendingSubscription; import com.raytheon.uf.common.datadelivery.registry.PendingSubscription; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; +import com.raytheon.uf.common.datadelivery.service.ApprovedPendingSubscriptionNotificationResponse; +import com.raytheon.uf.common.datadelivery.service.BaseSubscriptionNotificationResponse; +import com.raytheon.uf.common.datadelivery.service.DeniedPendingSubscriptionNotificationResponse; +import com.raytheon.uf.common.datadelivery.service.PendingSubscriptionNotificationResponse; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionApprovalDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionApprovalDlg.java index 304d826ca4..49a2d98101 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionApprovalDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionApprovalDlg.java @@ -40,6 +40,7 @@ import com.raytheon.uf.common.datadelivery.registry.PendingSubscription; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.handlers.IPendingSubscriptionHandler; import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.registry.handler.RegistryObjectHandlers; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -57,7 +58,6 @@ import com.raytheon.uf.viz.datadelivery.services.DataDeliveryServices; import com.raytheon.uf.viz.datadelivery.subscription.CancelForceApplyAndIncreaseLatencyDisplayText; import com.raytheon.uf.viz.datadelivery.subscription.IPermissionsService; import com.raytheon.uf.viz.datadelivery.subscription.IPermissionsService.IAuthorizedPermissionResponse; -import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionNotificationService; import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService; import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService.ISubscriptionServiceResult; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.ForceApplyPromptResponse; diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionDiff.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionDiff.java index 9b3a2de695..c798b52aee 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionDiff.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/approve/SubscriptionDiff.java @@ -52,6 +52,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Jul 25, 2012 955 djohnson Use List instead of ArrayList. * Sep 24, 2012 1157 mpduff Use InitialPendingSubsription. * Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes. + * Jan 25, 2013 1528 djohnson Compare priorities as primitive ints. * * * @@ -115,7 +116,7 @@ public class SubscriptionDiff { getMap(); - if (!(sub.getPriority().equals(pendingSub.getPriority()))) { + if (sub.getPriority() != pendingSub.getPriority()) { diffMap.put("priority", true); } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/presenter/CreateSubscriptionDlgPresenter.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/presenter/CreateSubscriptionDlgPresenter.java index ff508e7f9d..794c32f1fe 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/presenter/CreateSubscriptionDlgPresenter.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/presenter/CreateSubscriptionDlgPresenter.java @@ -44,10 +44,12 @@ import com.raytheon.uf.common.datadelivery.registry.InitialPendingSubscription; import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSet; import com.raytheon.uf.common.datadelivery.registry.PendingSubscription; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.datadelivery.registry.Utils.SubscriptionStatus; import com.raytheon.uf.common.datadelivery.registry.handlers.IPendingSubscriptionHandler; import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler; import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.registry.handler.RegistryObjectHandlers; @@ -62,7 +64,6 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.datadelivery.services.DataDeliveryServices; import com.raytheon.uf.viz.datadelivery.subscription.CancelForceApplyAndIncreaseLatencyDisplayText; import com.raytheon.uf.viz.datadelivery.subscription.GroupDefinitionManager; -import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionNotificationService; import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService; import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService.ISubscriptionServiceResult; import com.raytheon.uf.viz.datadelivery.subscription.view.ICreateSubscriptionDlgView; @@ -100,6 +101,9 @@ import com.raytheon.viz.ui.presenter.components.WidgetConf; * Jan 02, 2013 1441 djohnson Access GroupDefinitionManager in a static fashion. * Jan 04, 2012 1420 mpduff Add Latency to PriorityComp. * Jan 11, 2013 1453 djohnson Sets cycle times on construction. + * Jan 14, 2013 1286 djohnson Check that message to display is not null or empty, and + * only send notification of subscription creation on OK status. + * Jan 25, 2013 1528 djohnson Use priority enum instead of raw integers, default to existing priority on edit. * * * @author mpduff @@ -371,6 +375,10 @@ public class CreateSubscriptionDlgPresenter { view.setActiveEndDateBtnEnabled(false); } + if (!create) { + view.setPriority(subscription.getPriority()); + } + List cycleTimes = subscription.getTime().getCycleTimes(); if (cycleTimes != null) { List cycleStrings = new ArrayList(); @@ -502,8 +510,8 @@ public class CreateSubscriptionDlgPresenter { } // priority - int priorityInd = view.getPriority(); - subscription.setPriority(priorityInd); + SubscriptionPriority priority = view.getPriority(); + subscription.setPriority(priority); subscription.setOfficeID(LocalizationManager.getInstance() .getCurrentSite()); @@ -557,17 +565,21 @@ public class CreateSubscriptionDlgPresenter { job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(final IJobChangeEvent event) { - subscriptionNotificationService - .sendCreatedSubscriptionNotification( - subscription, username); final IStatus status = event.getResult(); - if (status.getMessage() != null) { + + final boolean subscriptionCreated = status.isOK(); + if (subscriptionCreated) { + sendSubscriptionNotification(subscription, + username); + } + + if (!Strings.isNullOrEmpty(status.getMessage())) { guiThreadTaskExecutor.runAsync(new Runnable() { @Override public void run() { if (!view.isDisposed()) { - if (status.isOK()) { + if (subscriptionCreated) { view.displayPopup( CREATED_TITLE, status.getMessage()); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedEnsembleSubsetTab.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedEnsembleSubsetTab.java new file mode 100644 index 0000000000..3bd98c2bec --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedEnsembleSubsetTab.java @@ -0,0 +1,177 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.datadelivery.subscription.subset; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; + +import com.raytheon.uf.common.datadelivery.registry.Ensemble; +import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.util.CollectionUtil; +import com.raytheon.uf.viz.datadelivery.subscription.subset.xml.SubsetXML; +import com.raytheon.viz.ui.widgets.duallist.DualList; +import com.raytheon.viz.ui.widgets.duallist.DualListConfig; +import com.raytheon.viz.ui.widgets.duallist.IUpdate; + +/** + * + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 3, 2013            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class GriddedEnsembleSubsetTab { + + private static final String NAME = "Ensemble Members"; + + private final Set listeners = new HashSet(); + + private final Ensemble ensemble; + + private DualList dualList; + + private boolean modified; + + public GriddedEnsembleSubsetTab(Composite parentComp, Ensemble ensemble) { + this.ensemble = ensemble; + init(parentComp); + } + + private void init(Composite parentComp) { + GridLayout gl = new GridLayout(1, false); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + + gl.horizontalSpacing = 0; + gl.verticalSpacing = 0; + gl.marginWidth = 0; + gl.marginHeight = 0; + + Group group = new Group(parentComp, SWT.NONE); + group.setText(getName()); + group.setLayout(gl); + group.setLayoutData(gd); + + DualListConfig dualListConfig = new DualListConfig(); + dualListConfig.setAvailableListLabel("Available Members:"); + dualListConfig.setSelectedListLabel("Selected Memebers:"); + dualListConfig.setListHeight(125); + dualListConfig.setListWidth(175); + dualListConfig.setShowUpDownBtns(false); + dualListConfig.setFullList(ensemble.getMembers()); + dualList = new DualList(group, SWT.NONE, dualListConfig, + new IUpdate() { + + @Override + public void selectionChanged() { + modified = true; + notifyListeners(); + } + + @Override + public void hasEntries(boolean entries) { + + } + }); + } + + public String getName() { + return NAME; + } + + public Ensemble getEnsembleWithSelection() { + Ensemble ensemble = new Ensemble(this.ensemble); + ensemble.setSelectedMembers(Arrays.asList(dualList + .getSelectedListItems())); + return ensemble; + } + + private void loadFromEnsemble(Ensemble ensemble) { + dualList.clearSelection(); + if (ensemble != null && ensemble.getSelectedMembers() != null) { + dualList.selectItems(ensemble.getSelectedMembers().toArray( + new String[0])); + } + } + + public void populateSubscription(Subscription subscription) { + subscription.setEnsemble(getEnsembleWithSelection()); + } + + public void loadFromSubscription(Subscription subscription) { + loadFromEnsemble(subscription.getEnsemble()); + } + + public void populateSubsetXML(SubsetXML subsetXml) { + subsetXml.setEnsemble(getEnsembleWithSelection()); + } + + public void loadFromSubsetXML(SubsetXML subsetXml) { + loadFromEnsemble(subsetXml.getEnsemble()); + } + + public boolean isValid() { + return !CollectionUtil.isNullOrEmpty(dualList.getSelectedListItems()); + } + + public boolean isModified() { + return modified; + } + + public void setModified(boolean modified) { + this.modified = modified; + } + + public void addListener(IDataSize listener) { + synchronized (this.listeners) { + listeners.add(listener); + } + } + + protected void notifyListeners() { + Collection listeners; + synchronized (this.listeners) { + listeners = new ArrayList( + this.listeners); + } + for (IDataSize listener : listeners) { + listener.updateDataSize(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedSubsetManagerDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedSubsetManagerDlg.java index 08310c7fdf..3d11bf9dd7 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedSubsetManagerDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedSubsetManagerDlg.java @@ -24,6 +24,7 @@ import java.io.StringWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,13 +35,18 @@ import java.util.TreeSet; import javax.xml.bind.JAXBException; import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; import org.geotools.geometry.jts.ReferencedEnvelope; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Ordering; import com.raytheon.uf.common.datadelivery.registry.DataSetMetaData; +import com.raytheon.uf.common.datadelivery.registry.Ensemble; import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet; import com.raytheon.uf.common.datadelivery.registry.GriddedDataSetMetaData; import com.raytheon.uf.common.datadelivery.registry.Subscription; @@ -77,6 +83,8 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils; * Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes. * Jan 04, 2013 1299 djohnson Add logging of invalid forecast hour information if it occurs again. * Jan 04, 2013 1420 mpduff Pass cycles in for rules. + * Jan 18, 2013 1414 bsteffen Add ensemble tab. + * Jan 28, 2013 1533 djohnson Update the calculated dataset size after loading subset xml. * * * @@ -115,6 +123,8 @@ public class GriddedSubsetManagerDlg private DataSetMetaData metaData; + private GriddedEnsembleSubsetTab ensembleTab; + /** * Constructor. * @@ -150,6 +160,83 @@ public class GriddedSubsetManagerDlg super(shell, dataSet); } + @Override + protected void createGridTabs(TabFolder tabFolder) { + super.createGridTabs(tabFolder); + Ensemble e = dataSet.getEnsemble(); + if (e != null && e.getMembers() != null) { + TabItem ensembleTabItem = new TabItem(tabFolder, SWT.NONE, 2); + Composite ensembleComp = new Composite(tabFolder, SWT.NONE); + ensembleComp.setLayout(new GridLayout(1, false)); + ensembleComp.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, + true, false)); + ensembleTabItem.setControl(ensembleComp); + ensembleTab = new GriddedEnsembleSubsetTab(ensembleComp, + dataSet.getEnsemble()); + ensembleTab.addListener(this); + ensembleTabItem.setText(ensembleTab.getName()); + } + } + + @Override + protected Collection getInvalidTabs() { + Collection invalidTabs = super.getInvalidTabs(); + if (ensembleTab != null && !ensembleTab.isValid()) { + invalidTabs.add(ensembleTab.getName()); + } + return invalidTabs; + } + + @Override + protected void populateSubsetXML(SubsetXML subset) { + super.populateSubsetXML(subset); + if (ensembleTab != null) { + ensembleTab.populateSubsetXML(subset); + } + } + + @Override + protected void loadFromSubsetXML(SubsetXML subsetXml) { + super.loadFromSubsetXML(subsetXml); + if (ensembleTab != null) { + ensembleTab.loadFromSubsetXML(subsetXml); + } + updateDataSize(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.datadelivery.subscription.subset.SubsetManagerDlg + * #loadFromSubscription + * (com.raytheon.uf.common.datadelivery.registry.Subscription) + */ + @Override + protected void loadFromSubscription(Subscription subscription) { + super.loadFromSubscription(subscription); + if (ensembleTab != null) { + ensembleTab.loadFromSubscription(subscription); + } + } + + @Override + protected boolean isDirty() { + boolean modified = super.isDirty(); + if (!modified && ensembleTab != null) { + modified = ensembleTab.isModified(); + } + return modified; + } + + @Override + protected void setClean() { + super.setClean(); + if (ensembleTab != null) { + ensembleTab.setModified(false); + } + } + /** * {@inheritDoc} */ @@ -186,6 +273,11 @@ public class GriddedSubsetManagerDlg time.setSelectedTimeIndices(fcstIndices); subscription.setTime(time); + + if (ensembleTab != null) { + ensembleTab.populateSubscription(subscription); + } + return subscription; } @@ -193,7 +285,7 @@ public class GriddedSubsetManagerDlg * {@inheritDoc} */ @Override - protected SpecificDateTimeXML getTimeXml() { + protected SpecificDateTimeXML getTimeXmlFromSubscription() { SpecificDateTimeXML timeXml = new SpecificDateTimeXML(); Time time = this.subscription.getTime(); List cycleTimes = time.getCycleTimes(); @@ -270,7 +362,12 @@ public class GriddedSubsetManagerDlg // Get the temporal data int numFcstHours = this.timingTabControls.getSelectedFcstHours().length; dataSize.setNumFcstHours(numFcstHours); - + if (ensembleTab != null) { + dataSize.setNumEnsembleMembers(ensembleTab + .getEnsembleWithSelection()); + } else { + dataSize.setNumEnsembleMembers(dataSet.getEnsemble()); + } // Get the Areal data ReferencedEnvelope envelope = this.spatialTabControls.getEnvelope(); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedTimingSelectionDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedTimingSelectionDlg.java index 473bd67b46..9624f13737 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedTimingSelectionDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedTimingSelectionDlg.java @@ -33,6 +33,7 @@ import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.viz.datadelivery.common.ui.PriorityComp; import com.raytheon.uf.viz.datadelivery.subscription.subset.presenter.IGriddedTimingSelectionDlgView; import com.raytheon.uf.viz.datadelivery.system.SystemRuleManager; @@ -55,6 +56,7 @@ import com.raytheon.viz.ui.presenter.components.ListConf; * Oct 11, 2012 1263 jpiatt Modified for cancel button * Nov 20, 2012 1286 djohnson Implement displayYesNoPopup. * Jan 04, 2013 1420 mpduff Add Priority Composite. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -137,7 +139,8 @@ public class GriddedTimingSelectionDlg extends CaveSWTDialog implements // Get latency value SystemRuleManager ruleManager = SystemRuleManager.getInstance(); int latency = ruleManager.getLatency(this.subscription, cycleTimes); - int priority = ruleManager.getPriority(this.subscription, cycleTimes); + SubscriptionPriority priority = ruleManager + .getPriority(this.subscription, cycleTimes); priorityComp = new PriorityComp(shell, latency, priority); gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false); @@ -337,7 +340,7 @@ public class GriddedTimingSelectionDlg extends CaveSWTDialog implements * {@inheritDoc} */ @Override - public int getPriority() { - return priorityComp.getPriorityIndex(); + public SubscriptionPriority getPriority() { + return priorityComp.getPriority(); } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/SubsetManagerDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/SubsetManagerDlg.java index e9c6a9e22f..f4040cc45f 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/SubsetManagerDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/SubsetManagerDlg.java @@ -20,7 +20,9 @@ package com.raytheon.uf.viz.datadelivery.subscription.subset; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -50,6 +52,7 @@ import com.raytheon.uf.common.datadelivery.registry.DataSet; import com.raytheon.uf.common.datadelivery.registry.DataType; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet; +import com.raytheon.uf.common.datadelivery.registry.Levels; import com.raytheon.uf.common.datadelivery.registry.Parameter; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.Time; @@ -122,6 +125,7 @@ import com.raytheon.viz.ui.presenter.IDisplay; * Jan 02, 2012 1345 djohnson Use gui thread task executor. * Jan 04, 2012 1420 mpduff Pass the subscription in to the GriddedTimingSelectionDlg. * Jan 10, 2013 1444 mpduff Fix the loading of saved subsets from the saved subset tab. + * Jan 28, 2013 1530 djohnson Break out long method chaining into local variables for debugging. * * * @author mpduff @@ -137,9 +141,6 @@ public abstract class SubsetManagerDlg tabTextMap = new HashMap(); - /** Subset Name text box */ private Text nameText; @@ -180,15 +181,6 @@ public abstract class SubsetManagerDlg tabsValidMap = new HashMap(); + Collection invalidTabs = getInvalidTabs(); + + if (!invalidTabs.isEmpty()) { + StringBuilder message = new StringBuilder( + "The following tabs do not have valid entries:\n\n"); + for (String tab : invalidTabs) { + message.append(tab + "\n"); + } + DataDeliveryUtils.showMessage(shell, getStyle(), "Invalid Entries", + message.toString()); + return false; + } + + return true; + } + + protected Collection getInvalidTabs() { + Collection invalidTabs = new ArrayList(3); // Get the tabs to validate // TODO Hardcoding the tabs for now, fix this later // Validate the vertical tab - tabsValidMap.put(VERTICAL_TAB, vTab.isValid()); + if (!vTab.isValid()) { + invalidTabs.add(VERTICAL_TAB); + } - tabsValidMap.put(TIMING_TAB, timingTabControls.isValid()); + if (!timingTabControls.isValid()) { + invalidTabs.add(TIMING_TAB); + } // Next is spatial subset tab - tabsValidMap.put(SPATIAL_TAB, spatialTabControls.isValid()); - - StringBuilder buf = new StringBuilder( - "The following tabs do not have valid entries:\n\n"); - boolean showMsg = false; - for (String tab : tabsValidMap.keySet()) { - if (!tabsValidMap.get(tab)) { - buf.append(tabTextMap.get(tab) + "\n"); - showMsg = true; - } + if (!spatialTabControls.isValid()) { + invalidTabs.add(SPATIAL_TAB); } - if (showMsg) { - DataDeliveryUtils.showMessage(shell, getStyle(), "Invalid Entries", - buf.toString()); - return false; - } - - return true; + return invalidTabs; } /** @@ -806,6 +796,15 @@ public abstract class SubsetManagerDlg subset = new SubsetXML(); + populateSubsetXML(subset); + + // Have all the info, now save the file + SubsetFileManager.getInstance().saveSubset(subset, this.shell); + setClean(); + subsetTab.enableButtons(nameText); + } + + protected void populateSubsetXML(SubsetXML subset) { subset.setBaseSubsetName(nameText.getText()); subset.setDatasetName(dataSet.getDataSetName()); subset.setProviderName(dataSet.getProviderName()); @@ -821,12 +820,6 @@ public abstract class SubsetManagerDlg loadedSubsetXml = (SubsetXML) SubsetFileManager .getInstance().loadSubset(subsetName); - updateSelections(loadedSubsetXml); + loadFromSubsetXML(loadedSubsetXml); } - /** - * Populate the dialog controls. - */ - private void populate() { - if (subsetXml == null) { - if (subscription == null) { - return; - } - populateSubset(); - } - - AreaXML area = subsetXml.getArea(); - spatialTabControls.setDataSet(this.dataSet); - spatialTabControls.populate(area); - + protected void loadFromSubsetXML(SubsetXML subsetXml) { ArrayList vertList = subsetXml.getVerticalList(); vTab.populate(vertList, dataSet); TIMEXML time = subsetXml.getTime(); this.timingTabControls.populate(time, dataSet); - this.nameText.setText(subsetXml.getBaseSubsetName()); + + if (this.subsetXml == subsetXml) { + // only populate area and name if subsetXml is loading from initial + // load, not from the saved subsets tab. + AreaXML area = subsetXml.getArea(); + spatialTabControls.setDataSet(this.dataSet); + spatialTabControls.populate(area); + + this.nameText.setText(subsetXml.getBaseSubsetName()); + } } - /** - * Update selections with from the loadedSubsetXML object. - */ - private void updateSelections(SubsetXML loadedSubsetXml) { - ArrayList vertList = loadedSubsetXml.getVerticalList(); - vTab.updateSettings(vertList); - - TIMEXML time = loadedSubsetXml.getTime(); - timingTabControls.updateSettings(time); - } - - /** - * Populate the subset object. - */ - private void populateSubset() { - subsetXml = new SubsetXML(); - subsetXml.setDatasetName(this.dataSet.getDataSetName()); - subsetXml.setProviderName(this.dataSet.getProviderName()); - subsetXml.setSubsetName(this.subscription.getName()); + protected void loadFromSubscription(Subscription subscription) { + this.nameText.setText(this.subscription.getName()); // Cycle time - TIMEXML timeXml = getTimeXml(); + TIMEXML timeXml = getTimeXmlFromSubscription(); timeXml.setLatestData(true); - subsetXml.setTime(timeXml); + this.timingTabControls.populate(timeXml, dataSet); // Area AreaXML area = new AreaXML(); @@ -911,7 +882,8 @@ public abstract class SubsetManagerDlg levelMap = new HashMap(); @@ -938,17 +910,20 @@ public abstract class SubsetManagerDlg selectedLevelIndices = levels + .getSelectedLevelIndices(); + for (int index : selectedLevelIndices) { + v.addLevel(String.valueOf(levels.getLevel() .get(index))); } } } } - for (VerticalXML v : levelMap.values()) { - subsetXml.addVertical(v); - } + ArrayList vertList = new ArrayList( + levelMap.values()); + vTab.populate(vertList, dataSet); } /** @@ -956,25 +931,22 @@ public abstract class SubsetManagerDlg vertList, DataSet dataSet) { + public void populate(List vertList, DataSet dataSet) { this.dataSet = dataSet; createExpandBarItems(); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java index 29cefc9159..e7ab74b795 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java @@ -19,8 +19,8 @@ **/ package com.raytheon.uf.viz.datadelivery.subscription.subset.presenter; -import java.util.ArrayList; -import java.util.Collections; +import static com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.getMaxLatency; + import java.util.List; import com.google.common.annotations.VisibleForTesting; @@ -44,6 +44,7 @@ import com.raytheon.viz.ui.presenter.components.ListConf; * Sep 27, 2012 1202 bgonzale Set selectionDate to date and cycle. * Oct 11, 2012 1263 jpiatt Modified for cancel flag. * Jan 04, 2013 1420 mpduff Add the dataset object. + * Jan 22, 2013 1519 djohnson Use DataDeliveryUtils.getMaxLatency(). * * * @@ -173,7 +174,7 @@ public class GriddedTimingSelectionPresenter { } DataDeliveryGUIUtils.latencyValidChk(view.getLatency(), - getMaxLatency()); + getMaxLatency(dataSet)); // parse off the date/cycle time selected String[] parts = selection.split(" - "); @@ -188,29 +189,6 @@ public class GriddedTimingSelectionPresenter { return true; } - /** - * Max latency value in minutes. - * - * @return - */ - private int getMaxLatency() { - List cycleList = new ArrayList(dataSet.getCycles()); - Collections.sort(cycleList); - - int max = 0; - - for (int i = 0; i < cycleList.size(); i++) { - if (i + 1 <= cycleList.size()) { - int tempMax = cycleList.get(i + 1) - cycleList.get(i); - if (tempMax > max) { - max = tempMax; - } - } - } - - return max * 60; - } - /** * This method is called via the "Use Latest Data" checkbox being * selected/unselected. diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/IGriddedTimingSelectionDlgView.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/IGriddedTimingSelectionDlgView.java index 6d1dd48a5f..7b5670d2a2 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/IGriddedTimingSelectionDlgView.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/IGriddedTimingSelectionDlgView.java @@ -19,6 +19,7 @@ **/ package com.raytheon.uf.viz.datadelivery.subscription.subset.presenter; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.viz.ui.presenter.IPresenterView; import com.raytheon.viz.ui.presenter.components.ButtonConf; import com.raytheon.viz.ui.presenter.components.CheckBoxConf; @@ -119,9 +120,9 @@ public interface IGriddedTimingSelectionDlgView extends IPresenterView { int getLatency(); /** - * Get the priority value. + * Get the priority. * - * @return priority value + * @return priority */ - int getPriority(); + SubscriptionPriority getPriority(); } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/xml/SubsetXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/xml/SubsetXML.java index bc23703671..afd773276f 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/xml/SubsetXML.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/xml/SubsetXML.java @@ -29,6 +29,7 @@ import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlRootElement; import com.raytheon.edex.util.Util; +import com.raytheon.uf.common.datadelivery.registry.Ensemble; import com.raytheon.uf.viz.datadelivery.common.xml.AreaXML; import com.raytheon.uf.viz.datadelivery.common.xml.IDisplayXml; @@ -65,6 +66,9 @@ public class SubsetXML implements IDisplayXml { @XmlElement(name = "area", type = AreaXML.class) protected AreaXML area; + + @XmlElement + protected Ensemble ensemble; @XmlElements({ @XmlElement(name = "vertical", type = VerticalXML.class) }) protected ArrayList verticalList = new ArrayList(); @@ -86,6 +90,21 @@ public class SubsetXML implements IDisplayXml { this.subsetName = subsetName; } + /** + * @return the ensemble + */ + public Ensemble getEnsemble() { + return ensemble; + } + + /** + * @param ensemble + * the ensemble to set + */ + public void setEnsemble(Ensemble ensemble) { + this.ensemble = ensemble; + } + /** * @return the area */ diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/view/ICreateSubscriptionDlgView.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/view/ICreateSubscriptionDlgView.java index 8787035a5b..ce32c9c679 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/view/ICreateSubscriptionDlgView.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/view/ICreateSubscriptionDlgView.java @@ -26,6 +26,7 @@ import java.util.Set; import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.viz.ui.presenter.IPresenterView; import com.raytheon.viz.ui.presenter.components.ButtonConf; import com.raytheon.viz.ui.presenter.components.CheckBoxConf; @@ -44,6 +45,7 @@ import com.raytheon.viz.ui.presenter.components.ComboBoxConf; * Dec 13, 2012 1391 bgonzale Added status methods. * Jan 02, 2013 1441 djohnson Add isGroupSelected. * Jan 04, 2013 1420 mpduff Added getters for latency and priority. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -210,14 +212,14 @@ public interface ICreateSubscriptionDlgView extends IPresenterView { * * @return */ - int getPriority(); + SubscriptionPriority getPriority(); /** * Set the priority selection * - * @param i + * @param subscriptionPriority */ - void setPriority(int i); + void setPriority(SubscriptionPriority subscriptionPriority); /** * Open the dialog @@ -406,13 +408,6 @@ public interface ICreateSubscriptionDlgView extends IPresenterView { */ int getLatencyValue(); - /** - * Get the priority value. - * - * @return - */ - int getPriorityValue(); - /** * Set Subscription. * diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/OperatorAdapter.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/OperatorAdapter.java index f30006ca1c..8130e8536d 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/OperatorAdapter.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/OperatorAdapter.java @@ -19,8 +19,12 @@ **/ package com.raytheon.uf.viz.datadelivery.subscription.xml; +import java.util.Collections; +import java.util.Map; + import javax.xml.bind.annotation.adapters.XmlAdapter; +import com.google.common.collect.Maps; import com.raytheon.uf.viz.datadelivery.system.Operator; import com.raytheon.uf.viz.datadelivery.system.OperatorTypes; import com.raytheon.uf.viz.datadelivery.utils.NameOperationItems; @@ -35,7 +39,8 @@ import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 7, 2013 1420 mpduff Initial creation. + * Jan 07, 2013 1420 mpduff Initial creation. + * Jan 14, 2013 1286 djohnson Add static versions of the conversion methods. * * * @@ -44,32 +49,61 @@ import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems; */ public class OperatorAdapter extends XmlAdapter> { - @Override - public Operator unmarshal(String v) throws Exception { - for (OperatorTypes ot : OperatorTypes.values()) { - if (ot.toString().equals(v)) { - return ot; - } - } - for (NameOperationItems noi : NameOperationItems.values()) { - if (noi.toString().equals(v)) { - return noi; - } + private static final Map> OPERATOR_MAP; + static { + Map> map = Maps.newHashMap(); + for (Operator operator : NameOperationItems.values()) { + map.put(toString(operator), operator); } - - for (TypeOperationItems toi : TypeOperationItems.values()) { - if (toi.toString().equals(v)) { - return toi; - } + for (Operator operator : OperatorTypes.values()) { + map.put(toString(operator), operator); } - - return null; + for (Operator operator : TypeOperationItems.values()) { + map.put(toString(operator), operator); + } + OPERATOR_MAP = Collections.unmodifiableMap(map); } + /** + * + * {@inheritDoc} + */ + @Override + public Operator unmarshal(String v) throws Exception { + return fromString(v); + } + + /** + * + * {@inheritDoc} + */ @Override public String marshal(Operator v) throws Exception { - return v.toString(); + return toString(v); + } + + /** + * Retrieve an {@link Operator} from its {@link String} representation. + * + * @param asString + * the string representation + * @return + */ + public static Operator fromString(String asString) { + return OPERATOR_MAP.get(asString); + } + + /** + * Retrieve the {@link String} representation of an {@link Operator} + * instance. + * + * @param operator + * the operator + * @return the {@link String} representation + */ + public static String toString(Operator operator) { + return operator.toString(); } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/PriorityRuleXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/PriorityRuleXML.java index 542d7efa88..f420df3ac7 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/PriorityRuleXML.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/PriorityRuleXML.java @@ -24,6 +24,8 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; + /** * Priority rule xml object. * @@ -34,6 +36,7 @@ import javax.xml.bind.annotation.XmlRootElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Dec 19, 2012 1420 mpduff Initial creation. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -44,20 +47,20 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class PriorityRuleXML extends RuleXML { @XmlElement(name = "priority") - private Integer priority; + private SubscriptionPriority priority; /** * @param priority * the priority to set */ - public void setPriority(Integer priority) { + public void setPriority(SubscriptionPriority priority) { this.priority = priority; } /** * @return the priority */ - public Integer getPriority() { + public SubscriptionPriority getPriority() { return priority; } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXML.java index 767178c76a..8ee0d441a1 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXML.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXML.java @@ -27,12 +27,10 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.datadelivery.registry.Subscription; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.units.DataSizeUnit; +import com.raytheon.uf.viz.datadelivery.system.CreateEditRuleDlg.FreqUnitOptions; import com.raytheon.uf.viz.datadelivery.system.Operator; import com.raytheon.uf.viz.datadelivery.system.OpsNetFieldNames; -import com.raytheon.uf.viz.datadelivery.utils.DataSizeUnit; /** * Parent Rules xml class @@ -44,6 +42,8 @@ import com.raytheon.uf.viz.datadelivery.utils.DataSizeUnit; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Dec 19, 2012 1420 mpduff Initial creation. + * Jan 14, 2013 1286 djohnson Correct string conversion of units and use {@link Operator}. + * Jan 17, 2013 1357 mpduff Moved DataSizeUnit. * * * @@ -53,11 +53,6 @@ import com.raytheon.uf.viz.datadelivery.utils.DataSizeUnit; @SuppressWarnings({ "unchecked", "rawtypes" }) @XmlAccessorType(XmlAccessType.NONE) public abstract class RuleXML { - - /** Status Handler */ - private final IUFStatusHandler statusHandler = UFStatus - .getHandler(RuleXML.class); - /** Rule name */ @XmlElement protected String ruleName; @@ -68,7 +63,7 @@ public abstract class RuleXML { /** Rule operator */ @XmlElement - protected String ruleOperator; + protected Operator ruleOperator; /** Rule value */ @XmlElement @@ -121,7 +116,7 @@ public abstract class RuleXML { * * @return the ruleOperator */ - public String getRuleOperator() { + public Operator getRuleOperator() { return ruleOperator; } @@ -131,7 +126,7 @@ public abstract class RuleXML { * @param ruleOperator * The operator value of the rule */ - public void setRuleOperator(String ruleOperator) { + public void setRuleOperator(Operator ruleOperator) { this.ruleOperator = ruleOperator; } @@ -192,38 +187,29 @@ public abstract class RuleXML { unit = getRuleUnit(); } - OperatorAdapter oa = new OperatorAdapter(); - Operator oper = null; - try { - oper = oa.unmarshal(ruleOperator); - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); - return false; - } - // If Data Name if (OpsNetFieldNames.NAME.toString().equals(ruleField)) { String dsName = sub.getDataSetName(); - return oper.evaluate(dsName, ruleValue); + return ruleOperator.evaluate(dsName, ruleValue); } // If Data Type if (OpsNetFieldNames.TYPE.toString().equals(ruleField)) { String dsType = sub.getDataSetType().toString(); - return oper.evaluate(ruleValue, dsType); + return ruleOperator.evaluate(ruleValue, dsType); } // If Data Size if (OpsNetFieldNames.SIZE.toString().equals(ruleField)) { long dsSizeKb = sub.getDataSetSize(); // Size in KB long ruleValueInt = Integer.parseInt(ruleValue); - DataSizeUnit dsUnit = DataSizeUnit.valueOf(unit); + DataSizeUnit dsUnit = DataSizeUnit.fromString(ruleUnit); ruleValueInt = dsUnit.toKB(ruleValueInt); - return oper.evaluate(Long.valueOf(dsSizeKb), + return ruleOperator.evaluate(Long.valueOf(dsSizeKb), Long.valueOf(ruleValueInt)); } @@ -231,7 +217,7 @@ public abstract class RuleXML { if (OpsNetFieldNames.FREQUENCY.toString().equals(ruleField)) { // Calculate frequency int ruleValueInt = Integer.parseInt(this.ruleValue); - if (unit.equalsIgnoreCase("Mins")) { + if (FreqUnitOptions.MIN.getOperation().equalsIgnoreCase(unit)) { ruleValueInt /= 60; } int freq = 0; @@ -246,7 +232,8 @@ public abstract class RuleXML { freq = val - tmp; } - if (oper.evaluate(Long.valueOf(freq), Long.valueOf(ruleValueInt))) { + if (ruleOperator.evaluate(Long.valueOf(freq), + Long.valueOf(ruleValueInt))) { return true; } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/CreateEditRuleDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/CreateEditRuleDlg.java index 6afc805872..228c42ea07 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/CreateEditRuleDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/CreateEditRuleDlg.java @@ -19,6 +19,7 @@ **/ package com.raytheon.uf.viz.datadelivery.system; +import java.util.List; import java.util.regex.Pattern; import org.eclipse.swt.SWT; @@ -35,15 +36,16 @@ import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.units.DataSizeUnit; import com.raytheon.uf.viz.datadelivery.subscription.xml.LatencyRuleXML; +import com.raytheon.uf.viz.datadelivery.subscription.xml.OperatorAdapter; import com.raytheon.uf.viz.datadelivery.subscription.xml.PriorityRuleXML; import com.raytheon.uf.viz.datadelivery.subscription.xml.RuleXML; import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils; -import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils.SubscriptionPriority; import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils; -import com.raytheon.uf.viz.datadelivery.utils.DataSizeUnit; import com.raytheon.uf.viz.datadelivery.utils.NameOperationItems; import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; @@ -65,6 +67,9 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * Dec 18, 2012 1417 bgonzale Changed value initialization in handleSave(). * Jan 04, 2013 1420 mpduff Remove code to apply rules changes to existing subscription, * rules are only for future subscriptions. + * Jan 14, 2013 1286 djohnson Rule operators are now used as objects. + * Jan 17, 2013 1357 mpduff Moved DataSizeUnit. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -225,6 +230,9 @@ public class CreateEditRuleDlg extends CaveSWTDialog { this(parent, create, null, ruleType); } + /** + * Create the rule header. + */ private void createRuleHeader() { if (create) { if (PRIORITY_TYPE.equals(ruleType)) { @@ -267,9 +275,9 @@ public class CreateEditRuleDlg extends CaveSWTDialog { protected void initializeComponents(Shell shell) { if (!create) { if (PRIORITY_TYPE.equals(ruleType)) { - ruleXml = srm.loadPriorityRule(ruleName); + ruleXml = srm.getPriorityRule(ruleName); } else { - ruleXml = srm.loadLatencyRule(ruleName); + ruleXml = srm.getLatencyRule(ruleName); } if (DATASET_SIZE.equals(ruleXml.getRuleField())) { @@ -409,7 +417,6 @@ public class CreateEditRuleDlg extends CaveSWTDialog { String item = fieldCombo.getItem(index); updateSelectionFields(item); } - }); OpsNetFieldNames[] fieldItems = OpsNetFieldNames.values(); @@ -448,7 +455,6 @@ public class CreateEditRuleDlg extends CaveSWTDialog { createFreqUnitItems(); } unitsCombo.select(0); - } if (PRIORITY_TYPE.equals(ruleType)) { @@ -479,7 +485,6 @@ public class CreateEditRuleDlg extends CaveSWTDialog { } priorityCombo.select(0); - } else { gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); gl = new GridLayout(3, false); @@ -505,19 +510,16 @@ public class CreateEditRuleDlg extends CaveSWTDialog { Label minutesLbl = new Label(latencySelectionComp, SWT.NONE); minutesLbl.setLayoutData(gd); minutesLbl.setText("Minutes"); - } populateFields(); ruleDefinitionGroup.pack(); - } /** * Upon edit, populate the fields. */ private void populateFields() { - if (!create) { String field = ruleXml.getRuleField(); if (!field.isEmpty()) { @@ -528,8 +530,8 @@ public class CreateEditRuleDlg extends CaveSWTDialog { updateSelectionFields(field); - String operator = ruleXml.getRuleOperator(); - operationCombo.select(operationCombo.indexOf(operator)); + operationCombo.select(operationCombo.indexOf(OperatorAdapter + .toString(ruleXml.getRuleOperator()))); String value = ruleXml.getRuleValue(); if (!value.isEmpty()) { @@ -542,17 +544,17 @@ public class CreateEditRuleDlg extends CaveSWTDialog { } if (PRIORITY_TYPE.equals(ruleType)) { - Integer priority = ((PriorityRuleXML) ruleXml).getPriority(); + SubscriptionPriority priority = ((PriorityRuleXML) ruleXml) + .getPriority(); - int o = 0; SubscriptionPriority[] priorityOptions = SubscriptionPriority .values(); for (SubscriptionPriority item : priorityOptions) { - if (priority == item.getPriorityValue()) { - priorityCombo.select(o); + if (priority == item) { + priorityCombo.select(priorityCombo.indexOf(priority + .getPriorityName())); break; } - o++; } } else { Integer latency = ((LatencyRuleXML) ruleXml).getLatency(); @@ -600,7 +602,6 @@ public class CreateEditRuleDlg extends CaveSWTDialog { close(); } }); - } /** @@ -646,8 +647,15 @@ public class CreateEditRuleDlg extends CaveSWTDialog { boolean valid = false; String fieldName = fieldCombo.getItem(fieldCombo.getSelectionIndex()); - String operator = operationCombo.getItem(operationCombo - .getSelectionIndex()); + Operator operator = OperatorAdapter.fromString(operationCombo + .getItem(operationCombo.getSelectionIndex())); + + List ruleNames = null; + if (PRIORITY_TYPE.equals(ruleType)) { + ruleNames = srm.getPriorityRuleNames(); + } else { + ruleNames = srm.getLatencyRuleNames(); + } if (create) { valid = DataDeliveryGUIUtils.hasText(ruleNameText); @@ -661,13 +669,29 @@ public class CreateEditRuleDlg extends CaveSWTDialog { } ruleName = ruleNameText.getText(); + + if (INVALID_PATTERN.matcher(ruleName.trim()).find()) { + DataDeliveryUtils.showMessage(getShell(), SWT.ERROR, + INVALID_CHARS_TITLE, INVALID_CHARS_MESSAGE); + return false; + } + + // Check for duplicate rule name + if (ruleNames.contains(ruleName)) { + DataDeliveryUtils + .showMessage( + shell, + SWT.ERROR, + "Duplicate Rule", + "A rule titled " + + ruleName + + " already exists.\n\nPlease select a different name."); + ruleNameText.selectAll(); + + return false; + } } - if (INVALID_PATTERN.matcher(ruleName.trim()).find()) { - DataDeliveryUtils.showMessage(getShell(), SWT.ERROR, - INVALID_CHARS_TITLE, INVALID_CHARS_MESSAGE); - return false; - } String value = null; if (DataDeliveryGUIUtils.hasText(ruleValue)) { value = ruleValue.getText(); @@ -709,12 +733,11 @@ public class CreateEditRuleDlg extends CaveSWTDialog { if (PRIORITY_TYPE.equals(ruleType)) { PriorityRuleXML rule = new PriorityRuleXML(); - priorityVal = SubscriptionPriority.valueOf(priorityCombo.getText() - .toUpperCase()); + priorityVal = SubscriptionPriority.fromPriorityName(priorityCombo + .getText()); for (SubscriptionPriority pri : SubscriptionPriority.values()) { if (pri.equals(priorityVal)) { - priority = pri.getPriorityValue(); - (rule).setPriority(priority); + rule.setPriority(pri); break; } } @@ -768,21 +791,12 @@ public class CreateEditRuleDlg extends CaveSWTDialog { } setReturnValue(saved); - - if (!saved) { - DataDeliveryUtils - .showMessage( - getShell(), - SWT.OK, - "Duplicate Name", - "A rule named " - + ruleName - + " already exists\n\nPlease select a different name."); - ruleNameText.selectAll(); - } return saved; } + /** + * Populate the units combo. + */ private void createSizeUnitItems() { unitsCombo.removeAll(); DataSizeUnit[] sizeUnits = DataSizeUnit.values(); @@ -791,6 +805,9 @@ public class CreateEditRuleDlg extends CaveSWTDialog { } } + /** + * Populate the operation combo. + */ private void createSizeOpItems() { operationCombo.removeAll(); OperatorTypes[] sizeOps = OperatorTypes.values(); @@ -799,6 +816,9 @@ public class CreateEditRuleDlg extends CaveSWTDialog { } } + /** + * Populate the frequency units combo. + */ private void createFreqUnitItems() { FreqUnitOptions[] freqUnits = FreqUnitOptions.values(); for (FreqUnitOptions fuo : freqUnits) { @@ -806,6 +826,9 @@ public class CreateEditRuleDlg extends CaveSWTDialog { } } + /** + * populate the operation combo. + */ private void createNameOpItems() { operationCombo.removeAll(); NameOperationItems[] nameOperation = NameOperationItems.values(); diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/DataViewUtils.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/IRulesUpdateListener.java similarity index 66% rename from edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/DataViewUtils.java rename to cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/IRulesUpdateListener.java index a9566df815..f393c815b7 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/DataViewUtils.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/IRulesUpdateListener.java @@ -1,54 +1,44 @@ /** * This software was developed and / or modified by Raytheon Company, * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * + * * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. - * + * * Contractor Name: Raytheon Company * Contractor Address: 6825 Pine Street, Suite 340 * Mail Stop B8 * Omaha, NE 68106 * 402.291.0100 - * + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.stats.util; +package com.raytheon.uf.viz.datadelivery.system; /** - * TODO Add Description - * + * Rules file update notifier interface. + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Nov 27, 2012            mpduff     Initial creation
- *
+ * Jan 16, 2013   1420     mpduff      Initial creation
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ -public class DataViewUtils { - public enum DataView { - AVG("Average"), MIN("Minimum"), MAX("Maximum"), - SUM("Sum"), COUNT("Count"); - - private final String view; - - private DataView(String view) { - this.view = view; - } - - public String getView() { - return view; - } - } +public interface IRulesUpdateListener { + /** + * Update rules. + */ + void update(); } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/Operator.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/Operator.java index 24a18be939..b365c06110 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/Operator.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/Operator.java @@ -19,6 +19,10 @@ **/ package com.raytheon.uf.viz.datadelivery.system; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.raytheon.uf.viz.datadelivery.subscription.xml.OperatorAdapter; + /** * Operator interface. * @@ -28,14 +32,15 @@ package com.raytheon.uf.viz.datadelivery.system; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 7, 2013 mpduff Initial creation + * Jan 07, 2013 mpduff Initial creation + * Jan 14, 2013 djohnson Specify JAXB adapter on the interface. * * * * @author mpduff * @version 1.0 */ - +@XmlJavaTypeAdapter(value = OperatorAdapter.class) public interface Operator { /** * Evaluate whether the operator would return true when comparing operandOne diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemLatencyTab.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemLatencyTab.java index c5a8aa5fa0..1e2a94f8b6 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemLatencyTab.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemLatencyTab.java @@ -52,6 +52,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils; * Sep 17, 2012 730 jpiatt Initial creation. * Oct 03, 2012 1241 djohnson Use {@link DataDeliveryPermission} and registry handlers. * Jan 04, 2012 1420 mpduff Add delete rule function. + * Jan 14, 2013 1286 djohnson Rule list is single item selectable. * * * @@ -134,7 +135,7 @@ public class SystemLatencyTab { gd.heightHint = 200; latencyList = new List(latencyComp, SWT.BORDER | SWT.MULTI - | SWT.V_SCROLL | SWT.H_SCROLL); + | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE); latencyList.setLayoutData(gd); latencyList.addSelectionListener(new SelectionAdapter() { @Override @@ -262,10 +263,7 @@ public class SystemLatencyTab { ruleDlg = new CreateEditRuleDlg(parentComp.getShell(), create, ruleName, LATENCY_TYPE); } - boolean reloadFlag = (Boolean) ruleDlg.open(); - if (reloadFlag) { - loadList(); - } + ruleDlg.open(); } else { ruleDlg.bringToTop(); } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemManagementDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemManagementDlg.java index 441f9eb9fa..bd45484a53 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemManagementDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemManagementDlg.java @@ -45,6 +45,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.util.StringUtil; +import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.ForceApplyPromptResponse; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.IForceApplyPromptDisplayText; import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils; @@ -64,6 +65,8 @@ import com.raytheon.viz.ui.presenter.IDisplay; * Oct 23, 2012 1286 djohnson Hook into bandwidth management. * Nov 20, 2012 1286 djohnson Implement IDisplay. * Jan 04, 2013 1420 mpduff Remove applying of rules. + * Jan 17, 2013 1501 djohnson Close the dialog when force apply occurs, + * and check whether changes have already been applied when OK is pressed. * * * @@ -71,7 +74,7 @@ import com.raytheon.viz.ui.presenter.IDisplay; * @version 1.0 */ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, - IForceApplyPromptDisplayText { + IForceApplyPromptDisplayText, IRulesUpdateListener { /** Status Handler */ private final IUFStatusHandler statusHandler = UFStatus @@ -128,10 +131,18 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, /** OK button */ private Button okBtn; + /** Available bandwidth modified flag */ private boolean availableBandwidthModified; + /** Available bandwidth spinner widget */ private Spinner availBandwidthSpinner; + /** The system latency tab */ + private SystemLatencyTab lTab; + + /** The system priority tab */ + private SystemPriorityTab pTab; + /** * Constructor. * @@ -141,6 +152,7 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, public SystemManagementDlg(Shell parent) { super(parent, SWT.DIALOG_TRIM, CAVE.NONE); setText("Data Delivery System Management"); + SystemRuleManager.getInstance().registerAsListener(this); } @@ -181,6 +193,17 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, } + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed() + */ + @Override + protected void disposed() { + super.disposed(); + SystemRuleManager.getInstance().deregisterAsListener(this); + } + /** * Create top bar route information. */ @@ -283,7 +306,7 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, priorityComp.setLayout(gl); priorityComp.setLayoutData(gd); priorityTab.setControl(priorityComp); - SystemPriorityTab pTab = new SystemPriorityTab(priorityComp); + pTab = new SystemPriorityTab(priorityComp); gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); gl = new GridLayout(1, false); @@ -296,7 +319,7 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, latencyComp.setLayout(gl); latencyComp.setLayoutData(gd); latencyTab.setControl(latencyComp); - SystemLatencyTab lTab = new SystemLatencyTab(latencyComp); + lTab = new SystemLatencyTab(latencyComp); gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false); gl = new GridLayout(1, false); @@ -309,6 +332,9 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, routingComp.setLayoutData(gd); routingTab.setControl(routingComp); SystemRoutingTab rTab = new SystemRoutingTab(routingComp); + + lTab.loadList(); + pTab.loadList(); } /** @@ -413,21 +439,26 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, sb.append("Would you like to change the bandwidth anyways?."); int response = DataDeliveryUtils.showMessage(getShell(), SWT.YES | SWT.NO, "Bandwidth Amount", sb.toString()); + boolean forceApplied = false; if (response == SWT.YES) { - boolean forceApplied = SystemRuleManager + forceApplied = SystemRuleManager .forceSetAvailableBandwidth(Network.OPSNET, bandwidth); - if (!forceApplied) { + if (forceApplied) { + availableBandwidthModified = false; + } else { statusHandler .handle(Priority.ERROR, "Bandwidth Change", "Unable to change the bandwidth for network " + Network.OPSNET + ". Please check the server for details."); - return false; + } } - return false; + return forceApplied; + } else { + availableBandwidthModified = false; } } @@ -466,4 +497,17 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay, "Don't know how to handle option [" + option + "]"); } } + + @Override + public void update() { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + if (!shell.isDisposed()) { + lTab.loadList(); + pTab.loadList(); + } + } + }); + } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemPriorityTab.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemPriorityTab.java index f39ce7daae..1d4635fd11 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemPriorityTab.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemPriorityTab.java @@ -268,10 +268,7 @@ public class SystemPriorityTab { create, ruleName, PRIORITY_TYPE); } - boolean reloadFlag = (Boolean) ruleDlg.open(); - if (reloadFlag) { - loadList(); - } + ruleDlg.open(); } else { ruleDlg.bringToTop(); } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemRuleManager.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemRuleManager.java index 5f1dc81a0b..66b08a0e95 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemRuleManager.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SystemRuleManager.java @@ -32,6 +32,9 @@ import javax.xml.bind.Unmarshaller; import com.raytheon.uf.common.datadelivery.bandwidth.IBandwidthService; import com.raytheon.uf.common.datadelivery.registry.Network; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; +import com.raytheon.uf.common.localization.FileUpdatedMessage; +import com.raytheon.uf.common.localization.ILocalizationFileObserver; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; @@ -64,6 +67,7 @@ import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems; * Sep 17, 2012 730 jpiatt Initial creation. * Oct 23, 2012 1286 djohnson Hook into bandwidth management. * Jan 04, 2013 1420 mpduff Move rules into a single file. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -89,6 +93,12 @@ public class SystemRuleManager { private final IUFStatusHandler statusHandler = UFStatus .getHandler(SystemRuleManager.class); + /** Latency Rules Localization File */ + private LocalizationFile latencyRulesLocFile; + + /** Priority Rules Localization File */ + private LocalizationFile priorityRulesLocFile; + /** JAXB context */ private JAXBContext jax; @@ -101,11 +111,21 @@ public class SystemRuleManager { /** Bandwidth service */ private IBandwidthService bandwidthService; + /** Latency Rules XML object */ + private LatencyRulesXML latencyRules; + + /** Priority Rules XML object */ + private PriorityRulesXML priorityRules; + + private final List listeners = new ArrayList(); + /** * Constructor. */ private SystemRuleManager() { createContext(); + loadLatencyRules(); + loadPriorityRules(); } /** @@ -144,7 +164,7 @@ public class SystemRuleManager { * @throws JAXBException */ public List getPriorityRuleNames() { - return getPriorityRules().getRuleNames(); + return getPriorityRules(false).getRuleNames(); } /** @@ -154,8 +174,8 @@ public class SystemRuleManager { * the name of the rule * @return the PriorityRuleXML object */ - public PriorityRuleXML loadPriorityRule(String name) { - PriorityRulesXML priorityRules = getPriorityRules(); + public PriorityRuleXML getPriorityRule(String name) { + PriorityRulesXML priorityRules = getPriorityRules(false); for (PriorityRuleXML rule : priorityRules.getRules()) { if (rule.getRuleName().equals(name)) { return rule; @@ -172,8 +192,8 @@ public class SystemRuleManager { * the name of the rule * @return the LatencyRuleXML object */ - public LatencyRuleXML loadLatencyRule(String name) { - LatencyRulesXML latencyRules = getLatencyRules(); + public LatencyRuleXML getLatencyRule(String name) { + LatencyRulesXML latencyRules = getLatencyRules(false); for (LatencyRuleXML rule : latencyRules.getRules()) { if (rule.getRuleName().equals(name)) { return rule; @@ -190,7 +210,7 @@ public class SystemRuleManager { * @throws JAXBException */ public List getLatencyRuleNames() { - return getLatencyRules().getRuleNames(); + return getLatencyRules(false).getRuleNames(); } /** @@ -203,15 +223,22 @@ public class SystemRuleManager { public boolean savePriorityRules(PriorityRulesXML xmlObj) { IPathManager pm = PathManagerFactory.getPathManager(); - LocalizationContext context = pm.getContext( - LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); - LocalizationFile priorityRulesLocFile = pm.getLocalizationFile(context, - this.PRIORITY_RULE_FILE); - try { - marshaller.marshal(xmlObj, priorityRulesLocFile.getFile()); - priorityRulesLocFile.save(); - return true; + // If site, then write out, otherwise save it as site. + if (priorityRulesLocFile.getContext().getLocalizationLevel() + .equals(LocalizationLevel.SITE)) { + marshaller.marshal(xmlObj, priorityRulesLocFile.getFile()); + return priorityRulesLocFile.save(); + } else { + LocalizationContext context = pm.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); + + priorityRulesLocFile = pm.getLocalizationFile(context, + this.PRIORITY_RULE_FILE); + addPriorityRulesFileObserver(); + marshaller.marshal(xmlObj, priorityRulesLocFile.getFile()); + return priorityRulesLocFile.save(); + } } catch (JAXBException e) { statusHandler.handle(Priority.ERROR, e.getLocalizedMessage(), e); } catch (LocalizationOpFailedException e) { @@ -231,15 +258,22 @@ public class SystemRuleManager { public boolean saveLatencyRules(LatencyRulesXML xmlObj) { IPathManager pm = PathManagerFactory.getPathManager(); - LocalizationContext context = pm.getContext( - LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); - LocalizationFile latencyRulesLocFile = pm.getLocalizationFile(context, - this.LATENCY_RULE_FILE); - try { - marshaller.marshal(xmlObj, latencyRulesLocFile.getFile()); - latencyRulesLocFile.save(); - return true; + // If site, then write out, otherwise save it as site. + if (latencyRulesLocFile.getContext().getLocalizationLevel() + .equals(LocalizationLevel.SITE)) { + marshaller.marshal(xmlObj, latencyRulesLocFile.getFile()); + return latencyRulesLocFile.save(); + } else { + LocalizationContext context = pm.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); + + latencyRulesLocFile = pm.getLocalizationFile(context, + this.LATENCY_RULE_FILE); + addLatencyRulesFileObserver(); + marshaller.marshal(xmlObj, latencyRulesLocFile.getFile()); + return latencyRulesLocFile.save(); + } } catch (JAXBException e) { statusHandler.handle(Priority.ERROR, e.getLocalizedMessage(), e); } catch (LocalizationOpFailedException e) { @@ -256,7 +290,7 @@ public class SystemRuleManager { * the rule name to delete */ public void deleteLatencyRule(String ruleName) { - LatencyRulesXML latencyRules = getLatencyRules(); + LatencyRulesXML latencyRules = getLatencyRules(false); for (LatencyRuleXML rule : latencyRules.getRules()) { if (rule.getRuleName().equals(ruleName)) { @@ -274,7 +308,7 @@ public class SystemRuleManager { * the rule name to delete */ public void deletePriorityRule(String ruleName) { - PriorityRulesXML priorityRules = getPriorityRules(); + PriorityRulesXML priorityRules = getPriorityRules(false); for (PriorityRuleXML rule : priorityRules.getRules()) { if (rule.getRuleName().equals(ruleName)) { @@ -293,7 +327,7 @@ public class SystemRuleManager { * @return true if updated */ public boolean updateRule(LatencyRuleXML rule) { - LatencyRulesXML rulesXml = getLatencyRules(); + LatencyRulesXML rulesXml = getLatencyRules(false); boolean saved = rulesXml.updateRule(rule); if (saved) { return saveLatencyRules(rulesXml); @@ -310,7 +344,7 @@ public class SystemRuleManager { * @return true if updated */ public boolean updateRule(PriorityRuleXML rule) { - PriorityRulesXML rulesXml = getPriorityRules(); + PriorityRulesXML rulesXml = getPriorityRules(false); boolean saved = rulesXml.updateRule(rule); if (saved) { saved = savePriorityRules(rulesXml); @@ -331,7 +365,7 @@ public class SystemRuleManager { * @return true if updated */ public boolean saveRule(PriorityRuleXML rule) { - PriorityRulesXML rulesXml = getPriorityRules(); + PriorityRulesXML rulesXml = getPriorityRules(false); boolean saved = rulesXml.addRule(rule); if (saved) { saved = savePriorityRules(rulesXml); @@ -352,7 +386,7 @@ public class SystemRuleManager { * @return true if updated */ public boolean saveRule(LatencyRuleXML rule) { - LatencyRulesXML rulesXml = getLatencyRules(); + LatencyRulesXML rulesXml = getLatencyRules(false); boolean saved = rulesXml.addRule(rule); if (saved) { saved = saveLatencyRules(rulesXml); @@ -368,19 +402,23 @@ public class SystemRuleManager { /** * Get the latency rules. * + * @param reread + * true to reread the file from disk + * * @return The latency rules xml object */ - private LatencyRulesXML getLatencyRules() { - LocalizationFile lfile = getRules(this.LATENCY_RULE_FILE); - - LatencyRulesXML latencyRules = new LatencyRulesXML(); - if (lfile != null && lfile.exists()) { - try { - latencyRules = (LatencyRulesXML) unmarshaller.unmarshal(lfile - .getFile()); - } catch (JAXBException e) { - statusHandler - .handle(Priority.ERROR, e.getLocalizedMessage(), e); + private LatencyRulesXML getLatencyRules(boolean reread) { + if (latencyRules == null || reread) { + if (this.latencyRulesLocFile != null + && latencyRulesLocFile.exists()) { + try { + latencyRules = (LatencyRulesXML) unmarshaller + .unmarshal(latencyRulesLocFile.getFile()); + } catch (JAXBException e) { + statusHandler.handle(Priority.ERROR, + e.getLocalizedMessage(), e); + latencyRules = new LatencyRulesXML(); + } } } @@ -390,34 +428,26 @@ public class SystemRuleManager { /** * Get the priority rules * + * @param reread + * true to reread the file from disk + * * @return The priority rules xml object */ - private PriorityRulesXML getPriorityRules() { - LocalizationFile lfile = getRules(this.PRIORITY_RULE_FILE); - - PriorityRulesXML priorityRules = new PriorityRulesXML(); - if (lfile != null && lfile.exists()) { - try { - priorityRules = (PriorityRulesXML) unmarshaller.unmarshal(lfile - .getFile()); - } catch (JAXBException e) { - statusHandler - .handle(Priority.ERROR, e.getLocalizedMessage(), e); + private PriorityRulesXML getPriorityRules(boolean reread) { + if (priorityRules == null || reread) + if (this.priorityRulesLocFile != null + && priorityRulesLocFile.exists()) { + try { + priorityRules = (PriorityRulesXML) unmarshaller + .unmarshal(priorityRulesLocFile.getFile()); + } catch (JAXBException e) { + statusHandler.handle(Priority.ERROR, + e.getLocalizedMessage(), e); + priorityRules = new PriorityRulesXML(); + } } - } - return priorityRules; - } - /** - * Get the rules files - * - * @param name - * Rules file name to get - * @return The localization file - */ - private LocalizationFile getRules(String name) { - IPathManager pm = PathManagerFactory.getPathManager(); - return pm.getStaticLocalizationFile(name); + return priorityRules; } /** @@ -442,7 +472,7 @@ public class SystemRuleManager { * @return */ public int getLatency(Subscription sub, Set cycleTimes) { - LatencyRulesXML rulesXml = this.getLatencyRules(); + LatencyRulesXML rulesXml = this.getLatencyRules(false); int latency = 999; boolean found = false; for (LatencyRuleXML rule : rulesXml.getRules()) { @@ -470,22 +500,23 @@ public class SystemRuleManager { * @param cycleTimes * @return */ - public int getPriority(Subscription sub, Set cycleTimes) { - PriorityRulesXML rulesXml = this.getPriorityRules(); - int priority = 3; - boolean found = false; + public SubscriptionPriority getPriority(Subscription sub, + Set cycleTimes) { + PriorityRulesXML rulesXml = this.getPriorityRules(false); + SubscriptionPriority priority = null; for (PriorityRuleXML rule : rulesXml.getRules()) { if (rule.matches(sub, cycleTimes)) { - if (rule.getPriority() < priority) { + if (priority == null + || rule.getPriority().getPriorityValue() < priority + .getPriorityValue()) { priority = rule.getPriority(); - found = true; } } } // Default to normal priority - if (!found) { - priority = 2; + if (priority == null) { + priority = SubscriptionPriority.NORMAL; } return priority; @@ -546,4 +577,87 @@ public class SystemRuleManager { return getInstance().bandwidthService .setBandwidthForNetworkInKilobytes(network, bandwidth); } + + /** + * Read the latency rules file. + */ + private void loadLatencyRules() { + IPathManager pm = PathManagerFactory.getPathManager(); + this.latencyRulesLocFile = pm + .getStaticLocalizationFile(this.LATENCY_RULE_FILE); + addLatencyRulesFileObserver(); + getLatencyRules(true); + } + + /** + * Load the priority rules file. + */ + private void loadPriorityRules() { + IPathManager pm = PathManagerFactory.getPathManager(); + this.priorityRulesLocFile = pm + .getStaticLocalizationFile(this.PRIORITY_RULE_FILE); + addPriorityRulesFileObserver(); + getPriorityRules(true); + } + + /** + * Add a file observer to the latency rules file to get notified when the + * file changes. + */ + private void addLatencyRulesFileObserver() { + latencyRulesLocFile + .addFileUpdatedObserver(new ILocalizationFileObserver() { + @Override + public void fileUpdated(FileUpdatedMessage message) { + loadLatencyRules(); + fireUpdates(); + } + }); + } + + /** + * Add a file observer to the priority rules file to get notified when the + * file changes. + */ + private void addPriorityRulesFileObserver() { + priorityRulesLocFile + .addFileUpdatedObserver(new ILocalizationFileObserver() { + @Override + public void fileUpdated(FileUpdatedMessage message) { + loadPriorityRules(); + fireUpdates(); + } + }); + } + + /** + * Notify the listeners the files changed. + */ + private void fireUpdates() { + for (IRulesUpdateListener listener : listeners) { + listener.update(); + } + } + + /** + * Register as a listener for rules file changes. + * + * @param listener + */ + public void registerAsListener(IRulesUpdateListener listener) { + if (!listeners.contains(listener)) { + listeners.add(listener); + } + } + + /** + * Unregister as a listener for rules files changed. + * + * @param listener + */ + public void deregisterAsListener(IRulesUpdateListener listener) { + if (listeners.contains(listener)) { + listeners.remove(listener); + } + } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryGUIUtils.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryGUIUtils.java index 516e1f0b59..0d0b1c6bed 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryGUIUtils.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryGUIUtils.java @@ -25,10 +25,7 @@ import java.util.Date; import java.util.TimeZone; import java.util.regex.Pattern; -import javax.xml.bind.annotation.XmlEnumValue; - import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; @@ -55,6 +52,7 @@ import com.raytheon.uf.viz.core.VizApp; * Dec 17, 2012 1435 mpduff Fix ThreadLocal implementation. * Dec 18, 2012 1439 mpduff Change Regex to match invalid chars. * Jan 04, 2013 1420 mpduff Change default priority to normal priority. + * Jan 25, 2013 1528 djohnson Subscription priority has moved up in the world to the Subscription class. * * * @@ -108,67 +106,6 @@ public class DataDeliveryGUIUtils { /** Name Required Message */ public static final String NAME_REQUIRED_MESSAGE = "Name required.\nA Subscription Name must be entered."; - /** Enumeration to use for subscription priorities */ - public static enum SubscriptionPriority { - /** High Priority */ - @XmlEnumValue("High") - HIGH("High", 1, new RGB(255, 0, 0)), - /** Default Priority */ - @XmlEnumValue("Normal") - NORMAL("Normal", 2, new RGB(0, 255, 0)), - /** Low Priority */ - @XmlEnumValue("Low") - LOW("Low", 3, new RGB(6, 122, 255)); - - /** Priority Setting */ - private final String priorityName; - - /** Numeric Value of the priority */ - private Integer priorityValue; - - /** Priority color for ui */ - private RGB color; - - private SubscriptionPriority(String priorityName, - Integer priorityValue, RGB color) { - this.priorityName = priorityName; - this.priorityValue = priorityValue; - this.color = color; - } - - /** - * Get column name. - * - * @return Priority Name - */ - public String getPriorityName() { - return priorityName; - } - - /** - * Get the integer value of the priority - * - * @return The integer value of the priority. - */ - public Integer getPriorityValue() { - return priorityValue; - } - - @Override - public String toString() { - return priorityName; - } - - /** - * Get the color. - * - * @return the color - */ - public RGB getColor() { - return color; - } - } - /** * Constructor. */ diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java index 929c03c1ce..2dc2e22296 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java @@ -32,6 +32,7 @@ import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.datadelivery.registry.Coverage; import com.raytheon.uf.common.datadelivery.registry.DataLevelType; +import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet; import com.raytheon.uf.common.datadelivery.registry.Parameter; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.Time; @@ -57,9 +58,11 @@ import com.vividsolutions.jts.geom.Coordinate; * Jul 25, 2012 955 djohnson Use List instead of ArrayList, thread-safe access to DecimalFormat. * Aug 29, 2012 223 mpduff Add cycles to the subscription details. * Oct 31, 2012 1278 mpduff Moved spatial methods to SpatialUtils. - * Nov 20, 2012 1286 djohnson Add showYesNoMessage. - * Dec 20, 2012 1413 bgonzale Added PendingSubColumnNames.valueOfColumnName(String). - * Jan 10, 2013 1420 mdpuff Added getMaxLatency(). + * Nov 20, 2012 1286 djohnson Add showYesNoMessage. + * Dec 20, 2012 1413 bgonzale Added PendingSubColumnNames.valueOfColumnName(String). + * Jan 10, 2013 1420 mdpuff Added getMaxLatency(). + * Jan 14, 2013 1286 djohnson Fix IndexOutOfBounds exception from getMaxLatency. + * Jan 22, 2013 1519 djohnson Correct getMaxLatency() calculations. * * * @author mpduff @@ -68,6 +71,18 @@ import com.vividsolutions.jts.geom.Coordinate; public class DataDeliveryUtils { + /** + * Default latency applied to hourly datasets. + */ + public static final int HOURLY_DATASET_LATENCY_IN_MINUTES = 40; + + /** + * Default latency applied non-hourly datasets. + */ + public static final int NON_HOURLY_DATASET_LATENCY_IN_MINUTES = 75; + + private static final int UNSET = -1; + /** Decimal format */ private final static ThreadLocal format = new ThreadLocal() { @@ -438,7 +453,8 @@ public class DataDeliveryUtils { .append(newline); fmtStr.append("Provider : ").append(sub.getProvider()).append(newline); fmtStr.append("Office ID: ").append(sub.getOfficeID()).append(newline); - fmtStr.append("Priority : ").append(sub.getPriority()).append(newline); + fmtStr.append("Priority : ") + .append(sub.getPriority().getPriorityValue()).append(newline); fmtStr.append("Coverage: ").append(newline); final Coverage coverage = sub.getCoverage(); @@ -550,18 +566,48 @@ public class DataDeliveryUtils { * @return the maximum latency in minutes */ public static int getMaxLatency(Subscription subscription) { - List cycles = subscription.getTime().getCycleTimes(); - Collections.sort(cycles); - int max = TimeUtil.HOURS_PER_DAY * TimeUtil.MINUTES_PER_HOUR; + return getMaxLatency(subscription.getTime().getCycleTimes()); + } - for (int i = 0; i < cycles.size(); i++) { - if (i + 1 <= cycles.size()) { - int tempMax = cycles.get(i + 1) - cycles.get(i); - if (tempMax > max) { - max = tempMax; - } + /** + * Get the maximum latency for the provided cycles. Calculated as the + * maximum cyclic difference. + * + * @param cycles + * The list of cycles + * @return the maximum latency in minutes + */ + public static int getMaxLatency(List cycles) { + Collections.sort(cycles); + int maximumTimeBetweenCycles = UNSET; + + final int size = cycles.size(); + for (int i = 0; i < size; i++) { + final int nextIndex = i + 1; + if (nextIndex < size) { + int tempMax = cycles.get(nextIndex) - cycles.get(i); + maximumTimeBetweenCycles = Math.max(maximumTimeBetweenCycles, tempMax); } } - return max; + + // If there was only one cycle, then default to the number of minutes in + // the day + if (maximumTimeBetweenCycles == UNSET) { + maximumTimeBetweenCycles = TimeUtil.HOURS_PER_DAY; + } + + return maximumTimeBetweenCycles * TimeUtil.MINUTES_PER_HOUR; + } + + /** + * Get the maximum latency for the provided dataSet. Calculated as the + * maximum cyclic difference. + * + * @param dataSet + * the dataset + * @return the maximum latency in minutes + */ + public static int getMaxLatency(GriddedDataSet dataSet) { + return getMaxLatency(new ArrayList(dataSet.getCycles())); } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java index e655eec99e..70d49d782c 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java @@ -21,6 +21,8 @@ package com.raytheon.uf.viz.datadelivery.utils; import java.util.List; +import com.raytheon.uf.common.time.util.TimeUtil; + /** * Data Set Frequency Enumeration. * @@ -30,7 +32,8 @@ import java.util.List; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 8, 2013 1420 mpduff Initial creation. + * Jan 08, 2013 1420 mpduff Initial creation. + * Jan 22, 2013 1519 djohnson Correct the non-hourly default latency to match requirements. * * * @@ -39,8 +42,11 @@ import java.util.List; */ public enum DataSetFrequency { - HOURLY(40), SIX_HOURLY(115), TWELVE_HOURLY(115), DAILY(115); - + HOURLY(DataDeliveryUtils.HOURLY_DATASET_LATENCY_IN_MINUTES), SIX_HOURLY( + DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES), TWELVE_HOURLY( + DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES), DAILY( + DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES); + private int defaultLatency; private DataSetFrequency(int defaultLatency) { @@ -49,13 +55,14 @@ public enum DataSetFrequency { public static DataSetFrequency fromCycleTimes(List cycleTimes) { if (cycleTimes.size() > 1) { - if ((cycleTimes.get(1) - cycleTimes.get(0)) == 1) { + final int hoursBetweenCycles = cycleTimes.get(1) - cycleTimes.get(0); + if (hoursBetweenCycles == 1) { return DataSetFrequency.HOURLY; - } else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 6) { + } else if (hoursBetweenCycles == TimeUtil.HOURS_PER_QUARTER_DAY) { return DataSetFrequency.SIX_HOURLY; - } else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 12) { + } else if (hoursBetweenCycles == TimeUtil.HOURS_PER_HALF_DAY) { return DataSetFrequency.TWELVE_HOURLY; - } else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 24) { + } else if (hoursBetweenCycles == TimeUtil.HOURS_PER_DAY) { return DataSetFrequency.DAILY; } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/NotificationHandler.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/NotificationHandler.java index 73d72c9391..2e1d7a5bfd 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/NotificationHandler.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/NotificationHandler.java @@ -9,13 +9,13 @@ import com.raytheon.uf.common.datadelivery.event.notification.DeleteNotification import com.raytheon.uf.common.datadelivery.event.notification.DeleteNotificationResponse; import com.raytheon.uf.common.datadelivery.event.notification.GetNotificationRequest; import com.raytheon.uf.common.datadelivery.event.notification.NotificationRecord; +import com.raytheon.uf.common.datadelivery.request.DataDeliveryConstants; +import com.raytheon.uf.common.serialization.comm.RequestRouter; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.notification.INotificationObserver; import com.raytheon.uf.viz.core.notification.NotificationException; import com.raytheon.uf.viz.core.notification.NotificationMessage; -import com.raytheon.uf.viz.core.requests.ThriftClient; import com.raytheon.uf.viz.datadelivery.notification.xml.MessageLoadXML; /** @@ -29,6 +29,7 @@ import com.raytheon.uf.viz.datadelivery.notification.xml.MessageLoadXML; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 12, 2012 jsanchez Initial creation + * Jan 22, 2013 1501 djohnson Route requests to datadelivery. * * * @@ -115,10 +116,10 @@ public class NotificationHandler implements INotificationObserver { request.setUsername(username); request.setHours(hours); request.setMaxResults(maxResults); - ArrayList response = (ArrayList) ThriftClient - .sendRequest(request); + ArrayList response = (ArrayList) RequestRouter + .route(request, DataDeliveryConstants.DATA_DELIVERY_SERVER); return response; - } catch (VizException e) { + } catch (Exception e) { statusHandler.error( "Error trying to retrieve notifications from database", e); } @@ -139,10 +140,10 @@ public class NotificationHandler implements INotificationObserver { try { DeleteNotificationRequest request = new DeleteNotificationRequest(); request.setIds(ids); - DeleteNotificationResponse response = (DeleteNotificationResponse) ThriftClient - .sendRequest(request); + DeleteNotificationResponse response = (DeleteNotificationResponse) RequestRouter + .route(request, DataDeliveryConstants.DATA_DELIVERY_SERVER); rowsDeleted = response.getRowsDeleted(); - } catch (VizException e) { + } catch (Exception e) { statusHandler.error( "Error trying to delete notification(s) from database", e); } diff --git a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/FFMPMonitor.java b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/FFMPMonitor.java index 2f3aac8815..d6b222114a 100644 --- a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/FFMPMonitor.java +++ b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/FFMPMonitor.java @@ -28,6 +28,7 @@ import org.eclipse.ui.PlatformUI; import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasin; import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData; +import com.raytheon.uf.common.dataplugin.ffmp.FFMPAggregateRecord; import com.raytheon.uf.common.dataplugin.ffmp.FFMPCacheRecord; import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceBasin; import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceInterpolation; @@ -53,6 +54,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.viz.core.HDF5Util; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.catalog.DirectDbQuery; @@ -88,6 +90,8 @@ import com.raytheon.uf.viz.monitor.listeners.IMonitorListener; * ------------ ---------- ----------- -------------------------- * 04/03/10 4494 D. Hladky Initial release * 12/07/12 1353 rferrel Changes for non-blocking FFMPSplash. + * 01/10/13 1475 D. Hladky Cleaned up some logging. + * 01/27/13 1478 D. Hladky revamped cache file format, removed duplicate times * * * @@ -473,28 +477,21 @@ public class FFMPMonitor extends ResourceMonitor { * @param siteKey * @param dataKey * @param source - * @param huc */ - public void insertFFMPData(FFMPBasinData data, String siteKey, - String source, String huc) { + public void insertFFMPData(FFMPAggregateRecord data, String siteKey, + String source) { - final String fsiteKey = siteKey; - final FFMPBasinData fdata = data; - final String fsource = source; - final String fhuc = huc; - - VizApp.runAsync(new Runnable() { - @Override - public void run() { - - if (ffmpData.containsKey(fsiteKey)) { - if (ffmpData.get(fsiteKey).containsKey(fsource)) { - ffmpData.get(fsiteKey).get(fsource) - .setBasinBuddyData(fdata, fhuc); - } + if (ffmpData.containsKey(siteKey)) { + if (ffmpData.get(siteKey).containsKey(source)) { + for (Entry entry : data.getBasinsMap() + .entrySet()) { + FFMPBasinData basinData = entry.getValue(); + basinData.populate(data.getTimes()); + ffmpData.get(siteKey).get(source) + .setCacheData(basinData, basinData.getHucLevel()); } } - }); + } } /** @@ -528,54 +525,35 @@ public class FFMPMonitor extends ResourceMonitor { public void populateFFMPBasin(String dataUri, String siteKey, String source, String phuc, FFMPBasin basin) throws VizException { - final String fdataUri = dataUri; - final String fsiteKey = siteKey; - final String fhuc = phuc; - final String fsource = source; - final FFMPBasin fbasin = basin; + if (dataUri != null) { + ConcurrentMap uris = getUriMap(siteKey, source, + phuc); + if (!uris.containsKey(dataUri)) { + try { + SourceXML sourceXML = fscm.getSource(source); + FFMPCacheRecord ffmpRec = populateFFMPRecord(true, dataUri, + siteKey, source, phuc); + File loc = HDF5Util.findHDF5Location(ffmpRec); + IDataStore dataStore = DataStoreFactory.getDataStore(loc); - VizApp.runAsync(new Runnable() { - @Override - public void run() { - - if (fdataUri != null) { - ConcurrentMap uris = getUriMap(fsiteKey, - fsource, fhuc); - if (!uris.containsKey(fdataUri)) { - try { - SourceXML sourceXML = fscm.getSource(fsource); - FFMPCacheRecord ffmpRec = populateFFMPRecord(true, - fdataUri, fsiteKey, fsource, fhuc); - // FFMPRecord ffmpRec = - // loadRecordFromDatabase(fdataUri); - File loc = HDF5Util.findHDF5Location(ffmpRec); - IDataStore dataStore = DataStoreFactory - .getDataStore(loc); - - if (sourceXML.getSourceType().equals( - SOURCE_TYPE.GAGE.getSourceType()) - && fhuc.equals("ALL")) { - ffmpRec.retrieveVirtualBasinFromDataStore( - dataStore, fdataUri, - getTemplates(fsiteKey), ffmpRec - .getDataTime().getRefTime(), - fbasin); - } else { - ffmpRec.retrieveBasinFromDataStore(dataStore, - fdataUri, getTemplates(fsiteKey), fhuc, - ffmpRec.getDataTime().getRefTime(), - ffmpRec.getSourceName(), fbasin); - } - } catch (Throwable e) { - statusHandler - .handle(Priority.PROBLEM, - "FFMP Can't retrieve FFMP URI, " - + fdataUri, e); - } + if (sourceXML.getSourceType().equals( + SOURCE_TYPE.GAGE.getSourceType()) + && phuc.equals("ALL")) { + ffmpRec.retrieveVirtualBasinFromDataStore(dataStore, + dataUri, getTemplates(siteKey), ffmpRec + .getDataTime().getRefTime(), basin); + } else { + ffmpRec.retrieveBasinFromDataStore(dataStore, dataUri, + getTemplates(siteKey), phuc, ffmpRec + .getDataTime().getRefTime(), ffmpRec + .getSourceName(), basin); } + } catch (Throwable e) { + statusHandler.handle(Priority.PROBLEM, + "FFMP Can't retrieve FFMP URI, " + dataUri, e); } } - }); + } } /** @@ -694,7 +672,7 @@ public class FFMPMonitor extends ResourceMonitor { if (source.getSourceType().equals( SOURCE_TYPE.GUIDANCE.getSourceType())) { - long timeOffset = source.getExpirationMinutes(siteKey) * 1000 * 60; + long timeOffset = source.getExpirationMinutes(siteKey) * TimeUtil.MILLIS_PER_MINUTE; earliestTime = new Date(time.getTime() - timeOffset); } @@ -977,7 +955,7 @@ public class FFMPMonitor extends ResourceMonitor { hucsToLoad.clear(); hucsToLoad.add("ALL"); timeBack = new Date(resource.getMostRecentTime().getTime() - - (3600 * 1000 * 24)); + - (TimeUtil.MILLIS_PER_HOUR * 24)); } frd.floader = new FFMPDataLoader(frd, timeBack, startTime, loadType, @@ -1149,10 +1127,13 @@ public class FFMPMonitor extends ResourceMonitor { res.getResourceData().floader = null; int val = siteCount.get(res.getSiteKey()); - // clear out the cache - for (Entry entry : ffmpData.get( - res.getSiteKey()).entrySet()) { - entry.getValue().closeCache(); + // never opened a cache + if (ffmpData.get(res.getSiteKey()) != null) { + // clear out the cache + for (Entry entry : ffmpData.get( + res.getSiteKey()).entrySet()) { + entry.getValue().closeCache(); + } } if ((val == 1) && (siteCount.size() > 1)) { @@ -2426,9 +2407,11 @@ public class FFMPMonitor extends ResourceMonitor { } } else { try { - statusHandler.handle(Priority.INFO, + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { + statusHandler.handle(Priority.DEBUG, "Retrieving and Populating URI: , " + dataUri); + } curRecord.retrieveMapFromDataStore(dataStore, dataUri, getTemplates(fffmpRec.getSiteKey()), fhuc, diff --git a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPDataLoader.java b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPDataLoader.java index e6650e9e25..7ce491a4f9 100644 --- a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPDataLoader.java +++ b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPDataLoader.java @@ -29,8 +29,9 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.NavigableMap; +import java.util.zip.GZIPInputStream; -import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData; +import com.raytheon.uf.common.dataplugin.ffmp.FFMPAggregateRecord; import com.raytheon.uf.common.monitor.config.FFMPRunConfigurationManager; import com.raytheon.uf.common.monitor.xml.FFMPRunXML; import com.raytheon.uf.common.monitor.xml.ProductRunXML; @@ -40,6 +41,10 @@ import com.raytheon.uf.common.ohd.AppsDefaults; import com.raytheon.uf.common.serialization.DynamicSerializationManager; import com.raytheon.uf.common.serialization.DynamicSerializationManager.SerializationType; import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.monitor.ffmp.FFMPMonitor; import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FFMPConfig; @@ -57,6 +62,7 @@ import com.raytheon.uf.viz.monitor.ffmp.ui.listeners.FFMPLoaderEvent; * ------------ ---------- ----------- -------------------------- * 28 Feb, 2011 7587 dhladky Initial creation * 25 Jan, 2012 DR13839 gzhang Handle Uris and Huc processing + * 01/27/13 1478 D. Hladky revamped the cache file format to help NAS overloading * * * @author dhladky @@ -64,8 +70,7 @@ import com.raytheon.uf.viz.monitor.ffmp.ui.listeners.FFMPLoaderEvent; */ public class FFMPDataLoader extends Thread { - // private static final transient IUFStatusHandler statusHandler = UFStatus - // .getHandler(FFMPDataLoader.class); + private static final IUFStatusHandler statusHandler = UFStatus.getHandler(FFMPDataLoader.class); private String sharePath = null; @@ -154,7 +159,7 @@ public class FFMPDataLoader extends Thread { ProductRunXML productRun = runner.getProduct(siteKey); ArrayList qpfSources = new ArrayList(); - + String layer = config.getFFMPConfigData().getLayer(); boolean isProductLoad = true; String rateURI = null; @@ -225,179 +230,159 @@ public class FFMPDataLoader extends Thread { hucsToLoad.add("ALL"); } - for (String phuc : hucsToLoad) { + if (isDone) { + return; + } - if (isDone) { - return; + // rate + if (rateURI != null) { + fireLoaderEvent(loadType, "Processing " + product.getRate(), + isDone); + for (String phuc : hucsToLoad) { + getMonitor().processUri(isProductLoad, rateURI, siteKey, + product.getRate(), timeBack, phuc); } + fireLoaderEvent(loadType, product.getRate(), isDone); + } - if (phuc.equals("VIRTUAL")) { - // we don't do the virtuals like this - continue; - } else { - // rate - if (rateURI != null) { - fireLoaderEvent(loadType, - "Processing " + product.getRate() + "/" + phuc, - isDone); + // qpes + fireLoaderEvent(loadType, "Processing " + product.getQpe(), isDone); + FFMPAggregateRecord qpeCache = null; - getMonitor().processUri(isProductLoad, rateURI, - siteKey, product.getRate(), timeBack, phuc); - fireLoaderEvent(loadType, product.getRate() + "/" - + phuc, isDone); + if (loadType == LOADER_TYPE.INITIAL) { + + SourceXML source = getMonitor().getSourceConfig().getSource( + product.getQpe()); + + qpeCache = readCacheFile(source, dataKey, wfo); + + if (qpeCache != null) { + getMonitor().insertFFMPData(qpeCache, siteKey, + product.getQpe()); + } + } + + // Use this method of QPE data retrieval if you don't have cache files + if (!qpeURIs.isEmpty() && qpeCache == null) { + for (String phuc : hucsToLoad) { + if (phuc.equals(layer) + || phuc.equals("ALL")) { + getMonitor().processUris(qpeURIs, isProductLoad, + siteKey, product.getQpe(), timeBack, phuc); } + } + } - // qpes - fireLoaderEvent(loadType, "Processing " + product.getQpe() - + "/" + phuc, isDone); - FFMPBasinData qpeData = null; + fireLoaderEvent(loadType, product.getQpe(), isDone); - if (loadType == LOADER_TYPE.INITIAL) { + int i = 0; + for (NavigableMap> qpfURIs : qpfs) { + // qpf + fireLoaderEvent(loadType, "Processing " + product.getQpf(i), + isDone); + FFMPAggregateRecord qpfCache = null; - SourceXML source = getMonitor().getSourceConfig() - .getSource(product.getQpe()); + if (loadType == LOADER_TYPE.INITIAL) { - qpeData = readLoaderBuddyFile(source, phuc, dataKey, - wfo); + SourceXML source = getMonitor().getSourceConfig() + .getSource(qpfSources.get(i)); - if (qpeData != null) { + String pdataKey = findQPFHomeDataKey(source); + qpfCache = readCacheFile(source, pdataKey, wfo); - getMonitor().insertFFMPData(qpeData, siteKey, - product.getQpe(), phuc); - } - } + if (qpfCache != null) { + for (String phuc : hucsToLoad) { + if ((phuc.equals(layer) || phuc.equals("ALL")) + && loadType == LOADER_TYPE.INITIAL + && source.getSourceName().equals( + config.getFFMPConfigData() + .getIncludedQPF())) { + if (!qpfURIs.isEmpty()) { - if (!qpeURIs.isEmpty() && qpeData == null) { - if (phuc.equals(config.getFFMPConfigData().getLayer()) - || phuc.equals("ALL")) { - getMonitor().processUris(qpeURIs, isProductLoad, - siteKey, product.getQpe(), timeBack, phuc); - } - } - - fireLoaderEvent(loadType, product.getQpe() + "/" + phuc, - isDone); - - int i = 0; - for (NavigableMap> qpfURIs : qpfs) { - // qpf - fireLoaderEvent(loadType, - "Processing " + product.getQpf(i) + "/" + phuc, - isDone); - FFMPBasinData qpfData = null; - if (loadType == LOADER_TYPE.INITIAL) { - - SourceXML source = getMonitor().getSourceConfig() - .getSource(qpfSources.get(i)); - - String pdataKey = findQPFHomeDataKey(source); - qpfData = readLoaderBuddyFile(source, phuc, - pdataKey, wfo); - - if (qpfData != null) { - - if ((phuc.equals(config.getFFMPConfigData() - .getLayer()) || phuc.equals("ALL")) - && loadType == LOADER_TYPE.INITIAL - && source.getSourceName().equals( - config.getFFMPConfigData() - .getIncludedQPF())) { - if (!qpfURIs.isEmpty()) { - - getMonitor().processUris(qpfURIs, - isProductLoad, siteKey, - source.getSourceName(), - timeBack, phuc); - } + getMonitor().processUris(qpfURIs, + isProductLoad, siteKey, + source.getSourceName(), timeBack, + phuc); } - - getMonitor().insertFFMPData(qpfData, siteKey, - source.getSourceName(), phuc); - } - } - // if (isUrisProcessNeeded(qpfData,qpfURIs)) - // {/*DR13839*/ - if ((qpfData == null) && !qpfURIs.isEmpty()) { - if (phuc.equals(config.getFFMPConfigData() - .getLayer()) || phuc.equals("ALL")) { // old - // code: - // keep - // for - // reference*/ - // if (isHucProcessNeeded(phuc)) {/*DR13839*/ - getMonitor().processUris(qpfURIs, - isProductLoad, siteKey, - product.getQpf(i), timeBack, phuc); } } - fireLoaderEvent(loadType, product.getQpf(i) + "/" - + phuc, isDone); - - i++; + getMonitor().insertFFMPData(qpfCache, siteKey, + source.getSourceName()); } - } - // virtuals only have data for ALL - if (phuc.equals("ALL")) { + // if (isUrisProcessNeeded(qpfData,qpfURIs)) + // {/*DR13839*/ + // Use this method of QPF data retrieval if you don't have cache files + if ((qpfCache == null) && !qpfURIs.isEmpty()) { + for (String phuc : hucsToLoad) { + if (phuc.equals(layer) + || phuc.equals("ALL")) { // old + // code: + // keep + // for + // reference*/ + // if (isHucProcessNeeded(phuc)) {/*DR13839*/ + getMonitor().processUris(qpfURIs, isProductLoad, + siteKey, product.getQpf(i), timeBack, phuc); + } + } + } + + fireLoaderEvent(loadType, product.getQpf(i), isDone); + + i++; + } + + fireLoaderEvent(loadType, "Processing " + product.getVirtual(), + isDone); + FFMPAggregateRecord vgbCache = null; + + if (loadType == LOADER_TYPE.INITIAL) { + + SourceXML source = getMonitor().getSourceConfig().getSource( + product.getVirtual()); + + vgbCache = readCacheFile(source, dataKey, wfo); + + if (vgbCache != null) { + + getMonitor().insertFFMPData(vgbCache, siteKey, + product.getVirtual()); + } + } + + // Use this method of Virtual data retrieval if you don't have cache files + if ((vgbCache == null) && !virtualURIs.isEmpty()) { + getMonitor().processUris(virtualURIs, isProductLoad, siteKey, + product.getVirtual(), timeBack, "ALL"); + } + + fireLoaderEvent(loadType, product.getVirtual(), isDone); + + // process guidance all for all only, never uses cache files + for (String type : productRun.getGuidanceTypes(product)) { + + ArrayList guidSources = productRun + .getGuidanceSources(product, type); + for (SourceXML guidSource : guidSources) { + + NavigableMap> iguidURIs = guids + .get(guidSource.getSourceName()); + fireLoaderEvent(loadType, - "Processing " + product.getVirtual() + "/" + phuc, + "Processing " + guidSource.getSourceName(), isDone); + + getMonitor().processUris(iguidURIs, isProductLoad, siteKey, + guidSource.getSourceName(), timeBack, "ALL"); + + fireLoaderEvent(loadType, guidSource.getSourceName(), isDone); - FFMPBasinData vgbData = null; - if (loadType == LOADER_TYPE.INITIAL) { - - SourceXML source = getMonitor().getSourceConfig() - .getSource(product.getVirtual()); - - vgbData = readLoaderBuddyFile(source, phuc, dataKey, - wfo); - - if (vgbData != null) { - - getMonitor().insertFFMPData(vgbData, siteKey, - product.getVirtual(), phuc); - } - } - - if ((vgbData == null) && !virtualURIs.isEmpty()) { - getMonitor().processUris(virtualURIs, isProductLoad, - siteKey, product.getVirtual(), timeBack, phuc); - } - - fireLoaderEvent(loadType, - product.getVirtual() + "/" + phuc, isDone); } - - // process guidance all at once - for (String type : productRun.getGuidanceTypes(product)) { - - ArrayList guidSources = productRun - .getGuidanceSources(product, type); - for (SourceXML guidSource : guidSources) { - - NavigableMap> iguidURIs = guids - .get(guidSource.getSourceName()); - - fireLoaderEvent(loadType, - "Processing " + guidSource.getSourceName() - + "/" + phuc, isDone); - - getMonitor().processUris(iguidURIs, isProductLoad, - siteKey, guidSource.getSourceName(), timeBack, - phuc); - - fireLoaderEvent(loadType, guidSource.getSourceName() - + "/" + phuc, isDone); - - } - } - - fireLoaderEvent(loadType, phuc + " Load complete", isDone); } } catch (Exception e) { - System.err.println("FFMP Data Loader terminated...." - + e.getMessage()); + statusHandler.handle(Priority.PROBLEM,"General Problem in Loading FFMP Data", e); } finally { isDone = true; } @@ -410,7 +395,7 @@ public class FFMPDataLoader extends Thread { } long endTime = (System.currentTimeMillis()) - time; - System.out.println("Loader took: " + endTime / 1000 + " seconds"); + System.out.println(loadType.loaderType + " Loader took: " + endTime / 1000 + " seconds"); fireLoaderEvent(loadType, message, isDone); } @@ -467,19 +452,19 @@ public class FFMPDataLoader extends Thread { }; /** - * Loads the loader buddy files + * Loads the Cache files * * @param sourceName * @param huc * @param wfo * @return */ - private FFMPBasinData readLoaderBuddyFile(SourceXML source, String huc, - String pdataKey, String wfo) { + private FFMPAggregateRecord readCacheFile(SourceXML source, String pdataKey, String wfo) { + long time = System.currentTimeMillis(); String sourceName = source.getSourceName(); File file = new File(sharePath + wfo + File.separator + sourceName - + "-" + siteKey + "-" + pdataKey + "-" + huc + ".bin"); + + "-" + siteKey + "-" + pdataKey + ".bin"); File lockFile = new File(sharePath + wfo + File.separator + sourceName + "-" + siteKey + "-" + pdataKey + ".lock"); @@ -489,22 +474,22 @@ public class FFMPDataLoader extends Thread { sleep(100); i++; } catch (InterruptedException e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR,"Took to long to load Cache Record", e); } } break; } - System.out.println("Buddy File expected path: " + System.out.println("Cache File expected path: " + file.getAbsolutePath()); - FFMPBasinData basinData = null; + FFMPAggregateRecord cacheRecord = null; if (file.exists()) { System.out.println("Last mod: " + new Date(file.lastModified())); - if (file.lastModified() > (System.currentTimeMillis() - (6 * 1000 * 3600))) { + if (file.lastModified() > (System.currentTimeMillis() - (6 * TimeUtil.MILLIS_PER_HOUR))) { while (lockFile.exists()) { for (int i = 0; i < 4; i++) { @@ -514,39 +499,42 @@ public class FFMPDataLoader extends Thread { sleep(100); i++; } catch (InterruptedException e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR,"ERROR in Loading Cache Record", e); } } break; } - BufferedInputStream is = null; + GZIPInputStream gis = null; try { System.out.println("Loading file: " + file.getName()); - is = new BufferedInputStream(new FileInputStream(file)); + gis = new GZIPInputStream(new BufferedInputStream(new FileInputStream(file))); DynamicSerializationManager dsm = DynamicSerializationManager .getManager(SerializationType.Thrift); - basinData = (FFMPBasinData) dsm.deserialize(is); + cacheRecord = (FFMPAggregateRecord) dsm.deserialize(gis); } catch (SerializationException e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR,"Serialization ERROR in Loading Cache Record", e); } catch (IOException e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR,"IO ERROR in Loading Cache Record", e); } finally { - if (is != null) { + if (gis != null) { try { - is.close(); + gis.close(); } catch (IOException e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR,"GENRAL ERROR in Loading Cache Record", e); } } } } } + + long time2 = System.currentTimeMillis(); + System.out.println("FFMP Cache file Load took: "+ (time2 - time) + " ms"); - return basinData; + return cacheRecord; } @@ -564,7 +552,7 @@ public class FFMPDataLoader extends Thread { for (ProductRunXML product : runManager.getProducts()) { File file = new File(sharePath + wfo + File.separator + source.getSourceName() + "-" + siteKey + "-" - + product.getProductKey() + "-ALL.bin"); + + product.getProductKey() + ".bin"); if (file.exists()) { return product.getProductKey(); @@ -572,7 +560,6 @@ public class FFMPDataLoader extends Thread { } return siteKey; - } } \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java index df28dcb877..f768f9d520 100644 --- a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java +++ b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java @@ -81,6 +81,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.viz.core.DrawableString; import com.raytheon.uf.viz.core.IDisplayPaneContainer; import com.raytheon.uf.viz.core.IGraphicsTarget; @@ -152,7 +153,8 @@ import com.vividsolutions.jts.geom.Point; * 31 July 2012 14517 mpduff Fix for blanking map on update. * 14 Sep 2012 1048 njensen Code cleanup * 07 Dec 2012 1353 rferrel Changes for non-blocking FFMPSplash dialog. - * + * 10 Jan 2013 1475 dhladky Some cleanup + * 27 Jan 2013 1478 dhladky Changed gap collection to a generic list insted of Arraylist * * * @author dhladky @@ -2070,6 +2072,7 @@ public class FFMPResource extends private void drawSquare(PixelCoverage pc, IGraphicsTarget target) throws VizException { + //target.drawLine(lines) target.drawLine(pc.getLl().x, pc.getLl().y, 0.0, pc.getUl().x, pc .getUl().y, 0.0, getCapability(ColorableCapability.class) .getColor(), getCapability(OutlineCapability.class) @@ -2455,10 +2458,6 @@ public class FFMPResource extends cwaBasins.clear(); try { - // String aggrHuc = "HUC0"; - // if (phuc.equals("COUNTY")) { - // aggrHuc = phuc; - // } // use the envelopes from HUC0 to speed processing // if necessary Map envMap = hucGeomFactory.getEnvelopes( @@ -2472,7 +2471,7 @@ public class FFMPResource extends } } } catch (Exception e) { - statusHandler.handle(Priority.WARN, "Domain: " + cwa + statusHandler.handle(Priority.DEBUG, "Domain: " + cwa + " Outside of site: " + getSiteKey() + " area..."); } } @@ -2901,7 +2900,7 @@ public class FFMPResource extends descriptor, 0.0f); if (req.shaded) { localShadedShape = req.target.createShadedShape(false, - descriptor, true); + descriptor.getGridGeometry(), true); } JTSCompiler jtsCompiler2 = new JTSCompiler(localShadedShape, @@ -3550,7 +3549,7 @@ public class FFMPResource extends synchronized (tableTime) { Date recentTime = getMostRecentTime(); - long time = new Double(recentTime.getTime() - (1000 * 3600) + long time = new Double(recentTime.getTime() - (TimeUtil.MILLIS_PER_HOUR) * getTime()).longValue(); Date date = new Date(); date.setTime(time); @@ -3724,7 +3723,7 @@ public class FFMPResource extends Date oldestCurrentTime = getResourceData().getAvailableTimes()[0] .getRefTime(); Date oldestTime = new Date(oldestCurrentTime.getTime() - - (1000 * 3600 * 24)); + - (TimeUtil.MILLIS_PER_HOUR * 24)); SortedSet keys = monitor.getAvailableUris(getSiteKey(), getDataKey(), getPrimarySource(), oldestTime).keySet(); @@ -3771,7 +3770,7 @@ public class FFMPResource extends - getTableTime().getTime(); sliderTime = Math - .floor(4 * (offset.doubleValue() / (1000 * 3600)) + .25) / 4; + .floor(4 * (offset.doubleValue() / (TimeUtil.MILLIS_PER_HOUR)) + .25) / 4; // sliderTime = Math.floor(((offset.doubleValue() / (1000 * 3600)) + // .005) * 100) / 100; setTime(sliderTime); @@ -3941,7 +3940,7 @@ public class FFMPResource extends * * @return Array of Gap data */ - public ArrayList getGaps() { + public List getGaps() { synchronized (timeOrderedKeys) { return FFMPGap.getGaps(getTimeOrderedKeys(), getResourceData() .getPrimarySourceXML().getExpirationMinutes(getSiteKey()), @@ -4010,7 +4009,7 @@ public class FFMPResource extends this.qpeSourceExpiration = monitor.getSourceConfig() .getSource(resourceData.getPrimarySource()) - .getExpirationMinutes(getSiteKey()) * 60 * 1000; + .getExpirationMinutes(getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE; } return qpeSourceExpiration; } @@ -4033,7 +4032,7 @@ public class FFMPResource extends source = FFMPSourceConfigurationManager.getInstance() .getSource(getResourceData().sourceName); } - qpfSourceExpiration = source.getExpirationMinutes(getSiteKey()) * 60 * 1000; + qpfSourceExpiration = source.getExpirationMinutes(getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE; } return qpfSourceExpiration; } @@ -4056,12 +4055,12 @@ public class FFMPResource extends SourceXML source = getProduct().getGuidanceSourcesByType( guidSrc).get(0); guidSourceExpiration = source - .getExpirationMinutes(getSiteKey()) * 60 * 1000; + .getExpirationMinutes(getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE; } else { guidSourceExpiration = monitor.getSourceConfig() .getSource(resourceData.getPrimarySource()) - .getExpirationMinutes(getSiteKey()) * 60 * 1000; + .getExpirationMinutes(getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE; } } @@ -4266,7 +4265,7 @@ public class FFMPResource extends } - return 3600 * 24 * 1000; + return 24 * TimeUtil.MILLIS_PER_HOUR; } /** @@ -4281,7 +4280,7 @@ public class FFMPResource extends if (status.isDone() && !this.getResourceData().isTertiaryLoad) { try { Date startDate = new Date(getMostRecentTime().getTime() - - (6 * 3600 * 1000)); + - (6 * TimeUtil.MILLIS_PER_HOUR)); FFMPMonitor.getInstance().startLoad(this, startDate, LOADER_TYPE.TERTIARY); } catch (VizException e) { diff --git a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResourceData.java b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResourceData.java index 98b9db188b..8d9b0ea1d0 100644 --- a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResourceData.java +++ b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResourceData.java @@ -50,6 +50,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.rsc.AbstractNameGenerator; import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; @@ -230,11 +231,8 @@ public class FFMPResourceData extends AbstractRequestableResourceData { DataTime mostRecentTime = availableTimes[availableTimes.length - 1]; this.timeBack = new Date( (long) (mostRecentTime.getRefTime().getTime() - (cfgBasinXML - .getTimeFrame() * 3600 * 1000))); + .getTimeFrame() * TimeUtil.MILLIS_PER_HOUR))); ArrayList hucsToLoad = monitor.getTemplates(siteKey).getTemplateMgr().getHucLevels(); - //ArrayList hucsToLoad = new ArrayList(); - //hucsToLoad.add(cfgBasinXML.getLayer()); - //hucsToLoad.add("ALL"); // goes back X hours and pre populates the Data Hashes FFMPDataLoader loader = new FFMPDataLoader(this, timeBack, mostRecentTime.getRefTime(), LOADER_TYPE.INITIAL, @@ -275,18 +273,28 @@ public class FFMPResourceData extends AbstractRequestableResourceData { this.domains = monitor.getRunConfig().getDomains(); SourceXML source = monitor.getSourceConfig().getSource( sourceName); + Date standAloneTime = null; if (source != null) { + // Special Loading for guidance sources, as mentioned in the comment + if (source.getDataType().equals(SOURCE_TYPE.GUIDANCE.getSourceType())) { + long oldestTime = availableTimes[0].getRefTime() + .getTime(); + long expirationTime = source + .getExpirationMinutes(siteKey) * TimeUtil.MILLIS_PER_MINUTE; + standAloneTime = new Date(oldestTime + - expirationTime); + } else { + // Only load current frames time + standAloneTime = availableTimes[availableTimes.length - 1] + .getRefTime(); + } - long oldestTime = availableTimes[0].getRefTime().getTime(); - long expirationTime = source.getExpirationMinutes(siteKey) * 60 * 1000; - Date standAloneTime = new Date(oldestTime - expirationTime); - NavigableMap> sourceURIs = getMonitor() - .getAvailableUris(siteKey, dataKey, sourceName, - standAloneTime); + .getAvailableUris(siteKey, dataKey, sourceName, + standAloneTime); getMonitor().processUris(sourceURIs, false, siteKey, - sourceName, standAloneTime, "ALL"); + sourceName, standAloneTime, "ALL"); } } } diff --git a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResource.java b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResource.java index cdf715f959..ee7def0588 100644 --- a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResource.java +++ b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResource.java @@ -54,7 +54,7 @@ import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; import com.raytheon.uf.viz.npp.crimss.CrimssNSharpResourceData; -import com.raytheon.viz.ui.MenuLoader; +import com.raytheon.viz.ui.BundleProductLoader; import com.raytheon.viz.ui.UiUtil; import com.raytheon.viz.ui.editor.AbstractEditor; import com.raytheon.viz.ui.input.EditableManager; @@ -218,7 +218,7 @@ public class CrimssMapResource extends display.cloneDisplay()); Bundle b = new Bundle(); b.setDisplays(new AbstractRenderableDisplay[] { display }); - Job j = new MenuLoader(b, editor); + Job j = new BundleProductLoader(editor, b); j.schedule(); } diff --git a/cave/com.raytheon.uf.viz.plugin.nwsauth/src/com/raytheon/uf/viz/plugin/nwsauth/NwsNotAuthHandler.java b/cave/com.raytheon.uf.viz.plugin.nwsauth/src/com/raytheon/uf/viz/plugin/nwsauth/NwsNotAuthHandler.java index 646a9bdbbc..cbf3c3616d 100644 --- a/cave/com.raytheon.uf.viz.plugin.nwsauth/src/com/raytheon/uf/viz/plugin/nwsauth/NwsNotAuthHandler.java +++ b/cave/com.raytheon.uf.viz.plugin.nwsauth/src/com/raytheon/uf/viz/plugin/nwsauth/NwsNotAuthHandler.java @@ -63,7 +63,7 @@ public class NwsNotAuthHandler implements INotAuthHandler { + request.getClass(); UFStatus.getHandler(NwsNotAuthHandler.class).handle(Priority.PROBLEM, message); - return null; + throw new VizException(message); } /* @@ -82,7 +82,7 @@ public class NwsNotAuthHandler implements INotAuthHandler { } UFStatus.getHandler(NwsNotAuthHandler.class).handle(Priority.PROBLEM, message); - return null; + throw new VizException(message); } } diff --git a/cave/com.raytheon.uf.viz.productbrowser/src/com/raytheon/uf/viz/productbrowser/AbstractRequestableProductBrowserDataDefinition.java b/cave/com.raytheon.uf.viz.productbrowser/src/com/raytheon/uf/viz/productbrowser/AbstractRequestableProductBrowserDataDefinition.java index d89159bf80..074c8de473 100644 --- a/cave/com.raytheon.uf.viz.productbrowser/src/com/raytheon/uf/viz/productbrowser/AbstractRequestableProductBrowserDataDefinition.java +++ b/cave/com.raytheon.uf.viz.productbrowser/src/com/raytheon/uf/viz/productbrowser/AbstractRequestableProductBrowserDataDefinition.java @@ -20,6 +20,7 @@ package com.raytheon.uf.viz.productbrowser; * further licensing information. **/ +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -50,7 +51,7 @@ import com.raytheon.uf.viz.core.rsc.ResourceProperties; import com.raytheon.uf.viz.core.rsc.ResourceType; import com.raytheon.uf.viz.productbrowser.ProductBrowserPreference.PreferenceType; import com.raytheon.viz.ui.EditorUtil; -import com.raytheon.viz.ui.MenuLoader; +import com.raytheon.viz.ui.BundleProductLoader; import com.raytheon.viz.ui.VizWorkbenchManager; import com.raytheon.viz.ui.editor.AbstractEditor; import com.raytheon.viz.ui.perspectives.AbstractVizPerspectiveManager; @@ -198,12 +199,15 @@ public abstract class AbstractRequestableProductBrowserDataDefinition pairs) { // retrieves the correct editor getEditor(); IDisplayPaneContainer container = getEditor(); @@ -213,11 +217,12 @@ public abstract class AbstractRequestableProductBrowserDataDefinition * @@ -38,133 +41,162 @@ import org.osgi.framework.Constants; */ public class Activator implements BundleActivator { - // The plug-in ID - public static final String PLUGIN_ID = "com.raytheon.uf.viz.spring.dm"; + // The plug-in ID + public static final String PLUGIN_ID = "com.raytheon.uf.viz.spring.dm"; - private static final String SPRING_PATH = "res" + IPath.SEPARATOR - + "spring"; + private static final String SPRING_PATH = "res" + IPath.SEPARATOR + + "spring"; - private static final String SPRING_FILE_EXT = "*.xml"; + private static final String SPRING_FILE_EXT = "*.xml"; - // The shared instance - private static Activator plugin; + // The shared instance + private static Activator plugin; - /** - * The constructor - */ - public Activator() { - } + /** + * The constructor + */ + public Activator() { + } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext context) throws Exception { - plugin = this; + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + if (this.isInstallOperation()) { + return; + } + plugin = this; - Map contextMap = new HashMap(); - Set processing = new HashSet(); - Bundle[] bundles = context.getBundles(); - Map bundleMap = new HashMap(); - for (Bundle b : bundles) { - bundleMap.put(b.getSymbolicName(), b); - } - for (Bundle b : bundles) { - createContext(bundleMap, contextMap, b, processing); - } - } + Map contextMap = new HashMap(); + Set processing = new HashSet(); + Bundle[] bundles = context.getBundles(); + Map bundleMap = new HashMap(); + for (Bundle b : bundles) { + bundleMap.put(b.getSymbolicName(), b); + } + for (Bundle b : bundles) { + createContext(bundleMap, contextMap, b, processing); + } + } - private OSGIXmlApplicationContext createContext( - Map bundles, - Map contextMap, Bundle bundle, - Set processing) { - String bundleName = bundle.getSymbolicName(); - OSGIXmlApplicationContext appCtx = contextMap.get(bundleName); - if (contextMap.containsKey(bundleName) == false - && bundleName.contains(".edex.") == false) { - if (processing.contains(bundleName)) { - throw new RuntimeException( - "Found recursive spring dependency while processing plugins: " - + bundleName); - } - processing.add(bundleName); + private OSGIXmlApplicationContext createContext( + Map bundles, + Map contextMap, Bundle bundle, + Set processing) { + String bundleName = bundle.getSymbolicName(); + OSGIXmlApplicationContext appCtx = contextMap.get(bundleName); + if (contextMap.containsKey(bundleName) == false + && bundleName.contains(".edex.") == false) { + if (processing.contains(bundleName)) { + throw new RuntimeException( + "Found recursive spring dependency while processing plugins: " + + bundleName); + } + processing.add(bundleName); - // No context created yet and not edex project, check for files - Enumeration entries = bundle.findEntries(SPRING_PATH, - SPRING_FILE_EXT, true); - if (entries != null) { - List files = new ArrayList(); - while (entries.hasMoreElements()) { - URL url = (URL) entries.nextElement(); - try { - url = FileLocator.toFileURL(url); - files.add(url.toString()); - } catch (IOException e) { - throw new RuntimeException( - "Error resolving spring file: " + url, e); - } - } - if (files.size() > 0) { - // Files found, check for dependencies - String requiredBundlesHeader = (String) bundle.getHeaders() - .get(Constants.REQUIRE_BUNDLE); - // Split comma separated string from MANIFEST - String[] requiredBundles = requiredBundlesHeader - .split("[,]"); - List parentContexts = new ArrayList(); - for (String requiredBndl : requiredBundles) { - // Extract bundle name which is first item in - // semicolon - // split list - String[] bndlParts = requiredBndl.split("[;]"); - Bundle reqBndl = bundles.get(bndlParts[0]); - if (reqBndl != null) { - // Found bundle, process context for bundle - OSGIXmlApplicationContext parent = createContext( - bundles, contextMap, reqBndl, processing); - if (parent != null) { - // Context found, add to list - parentContexts.add(parent); - } - } - } + // No context created yet and not edex project, check for files + Enumeration entries = bundle.findEntries(SPRING_PATH, + SPRING_FILE_EXT, true); + if (entries != null) { + List files = new ArrayList(); + while (entries.hasMoreElements()) { + URL url = (URL) entries.nextElement(); + try { + url = FileLocator.toFileURL(url); + files.add(url.toString()); + } catch (IOException e) { + throw new RuntimeException( + "Error resolving spring file: " + url, e); + } + } + if (files.size() > 0) { + // Files found, check for dependencies + String requiredBundlesHeader = (String) bundle.getHeaders() + .get(Constants.REQUIRE_BUNDLE); + // Split comma separated string from MANIFEST + String[] requiredBundles = requiredBundlesHeader + .split("[,]"); + List parentContexts = new ArrayList(); + for (String requiredBndl : requiredBundles) { + // Extract bundle name which is first item in + // semicolon + // split list + String[] bndlParts = requiredBndl.split("[;]"); + Bundle reqBndl = bundles.get(bndlParts[0]); + if (reqBndl != null) { + // Found bundle, process context for bundle + OSGIXmlApplicationContext parent = createContext( + bundles, contextMap, reqBndl, processing); + if (parent != null) { + // Context found, add to list + parentContexts.add(parent); + } + } + } - if (parentContexts.size() > 0) { - // Context with parent context - appCtx = new OSGIXmlApplicationContext( - new OSGIGroupApplicationContext(parentContexts), - files.toArray(new String[0]), bundle); - } else { - // No parent context required - appCtx = new OSGIXmlApplicationContext( - files.toArray(new String[0]), bundle); - } - } - } - contextMap.put(bundleName, appCtx); - } - processing.remove(bundleName); - return appCtx; - } + if (parentContexts.size() > 0) { + // Context with parent context + appCtx = new OSGIXmlApplicationContext( + new OSGIGroupApplicationContext(parentContexts), + files.toArray(new String[0]), bundle); + } else { + // No parent context required + appCtx = new OSGIXmlApplicationContext( + files.toArray(new String[0]), bundle); + } + } + } + contextMap.put(bundleName, appCtx); + } + processing.remove(bundleName); + return appCtx; + } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext context) throws Exception { - plugin = null; - } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + } - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Based on the command line arguments, determine whether or not an Eclipse + * p2 repository will be installed + * + * @return true if an Eclipse p2 repository is going to be installed, false + * otherwise + */ + private boolean isInstallOperation() { + final String P2_DIRECTOR = "org.eclipse.equinox.p2.director"; + + /** + * We look at the command line arguments instead of the program + * arguments (com.raytheon.uf.viz.application.ProgramArguments) because + * the command line arguments include almost everything that was passed + * as an argument to the Eclipse executable instead of just what CAVE is + * interested in. + */ + for (String argument : Platform.getCommandLineArgs()) { + if (P2_DIRECTOR.equals(argument)) { + return Boolean.TRUE; + } + } + + return Boolean.FALSE; + } } diff --git a/cave/com.raytheon.uf.viz.stats/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.stats/META-INF/MANIFEST.MF index bbc9e9368e..87e75da1c0 100644 --- a/cave/com.raytheon.uf.viz.stats/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.stats/META-INF/MANIFEST.MF @@ -12,7 +12,8 @@ Require-Bundle: org.eclipse.ui, com.raytheon.uf.common.stats;bundle-version="1.0.0", com.raytheon.uf.common.time;bundle-version="1.12.1174", com.raytheon.uf.common.util;bundle-version="1.12.1174", - com.google.guava;bundle-version="1.0.0" + com.google.guava;bundle-version="1.0.0", + com.raytheon.uf.common.units;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Export-Package: com.raytheon.uf.viz.stats, diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/GroupingComp.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/GroupingComp.java index 3f9e39259b..61bb2f5ae4 100644 --- a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/GroupingComp.java +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/GroupingComp.java @@ -20,7 +20,7 @@ package com.raytheon.uf.viz.stats.ui; /** - * TODO Add Description + * Grouping Composite for the Stats Graph. * *
  *
@@ -36,10 +36,13 @@ package com.raytheon.uf.viz.stats.ui;
  * @version 1.0
  */
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.eclipse.swt.SWT;
@@ -59,22 +62,25 @@ import org.eclipse.swt.widgets.ColorDialog;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Label;
 
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
 import com.raytheon.uf.common.stats.data.GraphData;
 
 /**
  * Composites that contains the controls to change colors and to determine what
  * is displayed.
- *
+ * 
  * 
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Oct 16, 2012            lvenable     Initial creation
- *
+ * Oct 16, 2012            lvenable    Initial creation
+ * Jan 11, 2013   1357     mpduff      Implement.
+ * 
  * 
- * + * * @author lvenable * @version 1.0 */ @@ -106,9 +112,11 @@ public class GroupingComp extends Composite implements IGroupSelection { /** Grouping callback */ private final IStatsGroup callback; + private final List selectionEntries = new ArrayList(); + /** * Constructor. - * + * * @param parentComp * Parent composite. * @param swtStyle @@ -191,12 +199,26 @@ public class GroupingComp extends Composite implements IGroupSelection { */ private void createControls() { List keyArray = graphData.getKeysWithData(); + Map> grpNameMap = graphData.getGroupAndNamesMap(); + // Create the Selection Entry objects for (String key : keyArray) { + SelectionEntry se = new SelectionEntry(); + String[] parts = colonPattern.split(key); + + Set grpNames = grpNameMap.keySet(); + Iterator iter = grpNames.iterator(); + for (int i = 0; i < grpNames.size(); i++) { + se.addPair(iter.next(), parts[i]); + } + this.selectionEntries.add(se); + } + + for (SelectionEntry se : selectionEntries) { GridData gd = new GridData(20, 10); Label lbl = new Label(controlComp, SWT.BORDER); lbl.setLayoutData(gd); - lbl.setData(key); + lbl.setData(se); lbl.addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { @@ -206,8 +228,9 @@ public class GroupingComp extends Composite implements IGroupSelection { }); Button btn = new Button(controlComp, SWT.CHECK); - btn.setText(key); + btn.setText(se.toString()); btn.setSelection(true); + btn.setData(se); btn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { @@ -216,8 +239,8 @@ public class GroupingComp extends Composite implements IGroupSelection { } }); - labelMap.put(key, lbl); - checkBtnMap.put(key, btn); + labelMap.put(se.toString(), lbl); + checkBtnMap.put(se.toString(), btn); } } @@ -245,22 +268,22 @@ public class GroupingComp extends Composite implements IGroupSelection { displaySelectionMgrDlg(); } }); -// Not including this functionality in the branch. -// gd = new GridData(buttonWidth, SWT.DEFAULT); -// Button colorMgrBtn = new Button(buttonComp, SWT.PUSH); -// colorMgrBtn.setText("Color Manager..."); -// colorMgrBtn.setLayoutData(gd); -// colorMgrBtn.addSelectionListener(new SelectionAdapter() { -// @Override -// public void widgetSelected(SelectionEvent e) { -// displayColorMgrDlg(); -// } -// }); + // Not including this functionality in the branch. + // gd = new GridData(buttonWidth, SWT.DEFAULT); + // Button colorMgrBtn = new Button(buttonComp, SWT.PUSH); + // colorMgrBtn.setText("Color Manager..."); + // colorMgrBtn.setLayoutData(gd); + // colorMgrBtn.addSelectionListener(new SelectionAdapter() { + // @Override + // public void widgetSelected(SelectionEvent e) { + // displayColorMgrDlg(); + // } + // }); } /** * Handle the check button event. - * + * * @param btn * Check box being checked/unchecked. */ @@ -278,13 +301,13 @@ public class GroupingComp extends Composite implements IGroupSelection { /** * Handle the color label that is being clicked. - * + * * @param lbl * Label that was clicked. */ private void handleLabelClickEvent(Label lbl) { RGB rgb = lbl.getBackground().getRGB(); - String key = (String) lbl.getData(); + String key = ((SelectionEntry) lbl.getData()).toString(); ColorDialog colorDlg = new ColorDialog(this.getShell()); colorDlg.setRGB(rgb); @@ -343,36 +366,30 @@ public class GroupingComp extends Composite implements IGroupSelection { if (selectionMangerDlg == null || selectionMangerDlg.isDisposed()) { selectionMangerDlg = new SelectionManagerDlg(getShell(), graphData, this); - selectionMangerDlg.open(); - } else { - selectionMangerDlg.bringToTop(); } + + selectionMangerDlg.open(); } /** * Display the Color Manager dialog. */ // Implementing in the next release. -// private void displayColorMgrDlg() { -// ColorManagerDlg dlg = new ColorManagerDlg(getShell(), graphData, this); -// dlg.open(); -// } + // private void displayColorMgrDlg() { + // ColorManagerDlg dlg = new ColorManagerDlg(getShell(), graphData, this); + // dlg.open(); + // } /** * {@inheritDoc} */ @Override public void setSelections(Map> selectionMap) { - List keySequence = graphData.getKeySequence(); - - Map> offMap = new HashMap>(); + Multimap offMap = ArrayListMultimap.create(); for (String key : selectionMap.keySet()) { for (String selection : selectionMap.get(key).keySet()) { if (!selectionMap.get(key).get(selection)) { - if (!offMap.containsKey(key)) { - offMap.put(key, new ArrayList()); - } - offMap.get(key).add(selection); + offMap.put(key, selection); } } } @@ -385,19 +402,18 @@ public class GroupingComp extends Composite implements IGroupSelection { } } else { for (String btnKey : checkBtnMap.keySet()) { - String[] parts = colonPattern.split(btnKey); + Button b = checkBtnMap.get(btnKey); + SelectionEntry se = (SelectionEntry) b.getData(); - for (String group : offMap.keySet()) { - for (String part : parts) { - int idx = keySequence.indexOf(part); - if (idx >= 0 && offMap.get(group).contains(keySequence.get(idx))) { - checkBtnMap.get(btnKey).setSelection(false); - keyRgbMap.remove(btnKey); - } else { - checkBtnMap.get(btnKey).setSelection(true); - keyRgbMap.put(btnKey, labelMap.get(btnKey) - .getBackground().getRGB()); - } + for (String key : offMap.keySet()) { + Collection valueList = offMap.get(key); + if (valueList.contains(se.getValue(key))) { + checkBtnMap.get(btnKey).setSelection(false); + keyRgbMap.remove(btnKey); + } else { + checkBtnMap.get(btnKey).setSelection(true); + keyRgbMap.put(btnKey, labelMap.get(btnKey) + .getBackground().getRGB()); } } } @@ -405,4 +421,33 @@ public class GroupingComp extends Composite implements IGroupSelection { fireCallback(); } + + /** + * {@inheritDoc} + */ + @Override + public void setItemsOff(List keys) { + for (String key : keys) { + if (checkBtnMap.containsKey(key)) { + checkBtnMap.get(key).setSelection(false); + keyRgbMap.remove(key); + } + } + + fireCallback(); + } + + /** + * {@inheritDoc} + */ + @Override + public Map getStates() { + Map stateMap = new HashMap(); + + for (Map.Entry state : checkBtnMap.entrySet()) { + stateMap.put(state.getKey(), state.getValue().getSelection()); + } + + return stateMap; + } } diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/HideDlg.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/HideDlg.java new file mode 100644 index 0000000000..82c9893bb2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/HideDlg.java @@ -0,0 +1,161 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.stats.ui; + +import java.util.Arrays; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Hide graph lines dialog. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 4, 2012    1357     mpduff      Initial creation.
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +public class HideDlg extends CaveSWTDialog { + /** Data List Widget */ + private List dataList; + + /** List of keys */ + private final java.util.List keyList; + + /** Callback to hide the lines */ + private final IGroupSelection callback; + + /** + * Constructor. + * + * @param parent + * The parent shell + * @param keyList + * The list of keys + * @param callback + * the callback + */ + public HideDlg(Shell parent, java.util.List keyList, + IGroupSelection callback) { + super(parent); + setText("Hide Graph Lines"); + + this.keyList = keyList; + this.callback = callback; + } + + /** + * {@inheritDoc} + */ + @Override + protected Layout constructShellLayout() { + // Create the main layout for the shell. + GridLayout mainLayout = new GridLayout(1, true); + mainLayout.marginHeight = 1; + mainLayout.marginWidth = 1; + return mainLayout; + } + + /** + * {@inheritDoc} + */ + @Override + protected void initializeComponents(Shell shell) { + setReturnValue(false); + + Composite mainComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.horizontalSpacing = 0; + gl.verticalSpacing = 5; + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + mainComp.setLayout(gl); + mainComp.setLayoutData(gd); + + GridData listData = new GridData(SWT.FILL, SWT.FILL, true, true); + listData.widthHint = 200; + listData.heightHint = 300; + dataList = new List(mainComp, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL + | SWT.H_SCROLL); + dataList.setLayoutData(listData); + dataList.setItems(keyList.toArray(new String[keyList.size()])); + + Composite buttonComp = new Composite(shell, SWT.NONE); + buttonComp.setLayout(new GridLayout(2, false)); + buttonComp.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true, + false)); + + int buttonWidth = 120; + gd = new GridData(buttonWidth, SWT.DEFAULT); + Button hideBtn = new Button(buttonComp, SWT.PUSH); + hideBtn.setText("Hide Graph Lines"); + hideBtn.setLayoutData(gd); + hideBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + handleHide(); + } + }); + + gd = new GridData(buttonWidth, SWT.DEFAULT); + Button closeBtn = new Button(buttonComp, SWT.PUSH); + closeBtn.setText("Close"); + closeBtn.setLayoutData(gd); + closeBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + }); + } + + /** + * Hide event handler + */ + private void handleHide() { + if (dataList.getSelectionCount() > 0) { + String[] itemsToHide = dataList.getSelection(); + callback.setItemsOff(Arrays.asList(itemsToHide)); + for (String item : itemsToHide) { + dataList.remove(item); + } + } + } +} diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IGroupSelection.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IGroupSelection.java index e6ba63b898..9f546562d2 100644 --- a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IGroupSelection.java +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IGroupSelection.java @@ -19,21 +19,23 @@ **/ package com.raytheon.uf.viz.stats.ui; +import java.util.List; import java.util.Map; /** * Interface for Group Selections. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Oct 18, 2012    728     mpduff     Initial creation
- *
+ * Oct 18, 2012    728     mpduff      Initial creation.
+ * Jan 17, 2013   1357     mpduff      Added setItemsOff and getStates.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -41,8 +43,23 @@ import java.util.Map; public interface IGroupSelection { /** * Set the selections. - * + * * @param selectionMap */ void setSelections(Map> selectionMap); + + /** + * Turn off the provided items. + * + * @param keys + * keys of the items to not draw + */ + void setItemsOff(List keys); + + /** + * Get the state of each item. + * + * @return Map of item -> checked or not checked + */ + Map getStates(); } diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IStatsDisplay.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IStatsDisplay.java index 12afff43ba..49ef4ef9a1 100644 --- a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IStatsDisplay.java +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/IStatsDisplay.java @@ -24,21 +24,21 @@ import java.util.Map; import org.eclipse.swt.graphics.RGB; import com.raytheon.uf.common.stats.data.GraphData; - +import com.raytheon.uf.common.stats.util.UnitUtils; /** * Stats display interface. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Oct 3, 2012     728     mpduff      Initial creation
- *
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -46,29 +46,36 @@ import com.raytheon.uf.common.stats.data.GraphData; public interface IStatsDisplay { /** * Get the GraphData object - * + * * @return GraphData */ GraphData getGraphData(); /** * Draw grid lines flag - * + * * @return true to draw the grid lines */ boolean drawGridLines(); /** * Draw data lines flag - * + * * @return true to draw the data lines */ boolean drawDataLines(); /** * Get the group settings. - * + * * @return The group settings map */ Map getGroupSettings(); + + /** + * Get the UnitUtils object. + * + * @return the UnitUtils object + */ + UnitUtils getUnitUtils(); } diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/SelectionEntry.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/SelectionEntry.java new file mode 100644 index 0000000000..b8b4620c8e --- /dev/null +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/SelectionEntry.java @@ -0,0 +1,87 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.stats.ui; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Stats Graph Item. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 24, 2013            mpduff     Initial creation
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ +public class SelectionEntry { + private final Map values = new LinkedHashMap(); + + private boolean checked = true; + + public SelectionEntry() { + + } + + public void addPair(String key, String value) { + values.put(key, value); + } + + public String getValue(String key) { + return values.get(key); + } + + /** + * @return the checked + */ + public boolean isChecked() { + return checked; + } + + /** + * @param checked + * the checked to set + */ + public void setChecked(boolean checked) { + this.checked = checked; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + for (Iterator iter = values.values().iterator(); iter.hasNext();) { + sb.append(iter.next()); + if (iter.hasNext()) { + sb.append(":"); + } + } + + return sb.toString(); + } +} diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/SelectionManagerDlg.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/SelectionManagerDlg.java index 71f48ae27d..d12231d3c5 100644 --- a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/SelectionManagerDlg.java +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/SelectionManagerDlg.java @@ -21,8 +21,10 @@ package com.raytheon.uf.viz.stats.ui; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; @@ -44,17 +46,18 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialogBase; /** * Stats Selection Manager Dialog. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Oct 18, 2012            lvenable     Initial creation
- *
+ * Oct 18, 2012            lvenable    Initial creation
+ * Jan 17, 2013  1357      mpduff      Added selection state handling.
+ * 
  * 
- * + * * @author lvenable * @version 1.0 */ @@ -74,9 +77,9 @@ public class SelectionManagerDlg extends CaveSWTDialogBase { /** * Constructor. - * + * * @param parentShell - * @param graphData + * @param selectionEntries * @param callback */ public SelectionManagerDlg(Shell parentShell, GraphData graphData, @@ -86,8 +89,8 @@ public class SelectionManagerDlg extends CaveSWTDialogBase { | CAVE.INDEPENDENT_SHELL); setText("Selection Manager"); - this.graphData = graphData; this.callback = callback; + this.graphData = graphData; } /** @@ -202,7 +205,7 @@ public class SelectionManagerDlg extends CaveSWTDialogBase { /** * Check the path of the item. - * + * * @param item * @param checked * @param grayed @@ -232,7 +235,7 @@ public class SelectionManagerDlg extends CaveSWTDialogBase { /** * Check or uncheck the items in the TreeItem - * + * * @param item * @param checked */ @@ -261,10 +264,27 @@ public class SelectionManagerDlg extends CaveSWTDialogBase { for (String subKey : array) { TreeItem subTreeItem = new TreeItem(treeItem, SWT.NONE); subTreeItem.setText(subKey); - subTreeItem.setChecked(true); } } + + // Determine group checkbox setting, unchecked, grayed, checked + TreeItem[] children = selectionTree.getItems(); + Set selectionSet = new HashSet(); + for (TreeItem item : children) { + item.setChecked(true); + for (TreeItem subItem : item.getItems()) { + selectionSet.add(subItem.getChecked()); + } + + if (selectionSet.contains(Boolean.TRUE) + && selectionSet.contains(Boolean.FALSE)) { + item.setChecked(true); + item.setGrayed(true); + } else if (!selectionSet.contains(Boolean.TRUE)) { + item.setChecked(false); + } + } } /** @@ -314,6 +334,5 @@ public class SelectionManagerDlg extends CaveSWTDialogBase { } else { callback.setSelections(selectionMap); } - } } diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsControlDlg.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsControlDlg.java index 013b15fec7..62e63e59f1 100644 --- a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsControlDlg.java +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsControlDlg.java @@ -69,7 +69,8 @@ import com.raytheon.viz.ui.widgets.duallist.IUpdate; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Sep 25, 2012 mpduff Initial creation + * Sep 25, 2012 1357 mpduff Initial creation. + * Jan 17, 2013 1357 mpduff Added timestep settings. * *
* @@ -92,7 +93,7 @@ public class StatsControlDlg extends CaveSWTDialog implements IStatsControl, TimeUtil.MILLIS_PER_HOUR * 3, TimeUtil.MILLIS_PER_HOUR * 6, TimeUtil.MILLIS_PER_HOUR * 12, TimeUtil.MILLIS_PER_DAY, TimeUtil.MILLIS_PER_WEEK, TimeUtil.MILLIS_PER_WEEK * 2, - TimeUtil.MILLIS_PER_MONTH }; + TimeUtil.MILLIS_PER_30_DAYS }; /** Date Format object */ private final ThreadLocal sdf = new ThreadLocal() { @@ -619,7 +620,24 @@ public class StatsControlDlg extends CaveSWTDialog implements IStatsControl, } TimeRange tr = new TimeRange(start, end); request.setTimeRange(tr); - request.setTimeStep(5); + + if (tr.getDuration() <= TimeUtil.MILLIS_PER_HOUR) { + request.setTimeStep(5); + } else if (tr.getDuration() <= TimeUtil.MILLIS_PER_HOUR * 3) { + request.setTimeStep(5); + } else if (tr.getDuration() <= TimeUtil.MILLIS_PER_HOUR * 6) { + request.setTimeStep(10); + } else if (tr.getDuration() <= TimeUtil.MILLIS_PER_HOUR * 12) { + request.setTimeStep(20); + } else if (tr.getDuration() <= TimeUtil.MILLIS_PER_HOUR * 24) { + request.setTimeStep(40); + } else if (tr.getDuration() <= TimeUtil.MILLIS_PER_DAY * 7) { + request.setTimeStep(240); + } else if (tr.getDuration() <= TimeUtil.MILLIS_PER_DAY * 14) { + request.setTimeStep(480); + } else { + request.setTimeStep(1000); + } try { GraphDataResponse response = (GraphDataResponse) ThriftClient diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsDisplayCanvas.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsDisplayCanvas.java index b6a26959d7..8ef620b160 100644 --- a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsDisplayCanvas.java +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsDisplayCanvas.java @@ -23,15 +23,19 @@ import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TimeZone; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.PaintEvent; @@ -47,31 +51,41 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.stats.data.DataPoint; import com.raytheon.uf.common.stats.data.GraphData; import com.raytheon.uf.common.stats.data.StatsData; -import com.raytheon.uf.common.stats.util.DataViewUtils; +import com.raytheon.uf.common.stats.util.DataView; +import com.raytheon.uf.common.stats.util.UnitUtils; +import com.raytheon.uf.common.stats.util.UnitUtils.TimeConversion; +import com.raytheon.uf.common.stats.util.UnitUtils.UnitTypes; import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.units.DataSizeUnit; import com.raytheon.uf.viz.core.RGBColors; import com.raytheon.uf.viz.stats.display.ScaleManager; /** * Statistics graph canvas. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Oct 3, 2012     728     mpduff      Initial creation
- *
+ * Oct 03, 2012     728    mpduff      Initial creation.
+ * Jan 17, 2013    1357    mpduff      Added mouse listeners.
+ * Jan 29, 2013    1523    mpduff      Fix for count units.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -106,6 +120,15 @@ public class StatsDisplayCanvas extends Canvas { } }; + /** Decimal Format object */ + private final ThreadLocal decFormat = new ThreadLocal() { + @Override + protected DecimalFormat initialValue() { + DecimalFormat format = new DecimalFormat("########.#"); + return format; + } + }; + /** Constant */ private final String COLON = ":"; @@ -185,21 +208,18 @@ public class StatsDisplayCanvas extends Canvas { /** Tooltip shell */ private Shell tooltip; - /** Graph Data object */ - private GraphData graphData; + /** Data View, avg, min, max, etc. */ + private DataView view = DataView.AVG; - /** Smallest value in the data set */ - private double minValue; + /** Group selection callback */ + private IGroupSelection groupCallback; - /** Largest value in the data set */ - private double maxValue; - - private String view = DataViewUtils.DataView.AVG.getView(); // Defaults to - // average + /** Hide dataset dialog */ + private HideDlg hideDlg; /** * Constructor - * + * * @param parent * Parent composite * @param callback @@ -214,8 +234,7 @@ public class StatsDisplayCanvas extends Canvas { this.callback = callback; this.graphTitle = graphTitle; - this.graphData = callback.getGraphData(); - TimeRange tr = graphData.getTimeRange(); + TimeRange tr = callback.getGraphData().getTimeRange(); String start = titleDateFormat.get().format(tr.getStart()); String end = titleDateFormat.get().format(tr.getEnd()); @@ -258,11 +277,18 @@ public class StatsDisplayCanvas extends Canvas { handleMouseMoveEvent(e); } }); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + handleMouseDownEvent(e); + } + }); } /** * Initialize drawing settings. - * + * * @param gc * The Graphics Context */ @@ -280,7 +306,7 @@ public class StatsDisplayCanvas extends Canvas { /** * Draw on the canvas. - * + * * @param gc * The Graphics Context */ @@ -327,7 +353,7 @@ public class StatsDisplayCanvas extends Canvas { /** * Draw the X axis. - * + * * @param gc * The Graphics Context */ @@ -342,8 +368,7 @@ public class StatsDisplayCanvas extends Canvas { List dateList = new ArrayList(); SimpleDateFormat sdf = axisFormat.get(); - - TimeRange tr = graphData.getTimeRange(); + TimeRange tr = callback.getGraphData().getTimeRange(); dateList.add(tr.getStart()); // Add the first date long milliRange = tr.getDuration(); @@ -356,24 +381,29 @@ public class StatsDisplayCanvas extends Canvas { long startMillis = tr.getStart().getTime(); StringBuilder buffer = new StringBuilder(); - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + Calendar cal = TimeUtil.newGmtCalendar(); for (long i = tr.getStart().getTime(); i <= tr.getEnd().getTime(); i += TimeUtil.MILLIS_PER_HOUR) { cal.setTimeInMillis(i); int[] tickArray = { - (int) (GRAPH_BORDER + (i - startMillis) / millisPerPixelX), + Math.round(GRAPH_BORDER + (i - startMillis) + / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT, - (int) (GRAPH_BORDER + (i - startMillis) / millisPerPixelX), + Math.round(GRAPH_BORDER + (i - startMillis) + / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT + height }; - if (cal.get(Calendar.HOUR_OF_DAY) == 0) { + if (cal.get(Calendar.HOUR_OF_DAY) == 0 + && cal.get(Calendar.MINUTE) == 0) { gc.setLineWidth(3); } else { gc.setLineWidth(1); } int hour = cal.get(Calendar.HOUR_OF_DAY); + // Draw the tick marks if ((numHours / 24 <= 7) || (hour % 6) == 0) { gc.drawPolyline(tickArray); + // Draw grid lines if (callback.drawGridLines()) { boolean draw = false; if (numHours <= 6) { @@ -386,19 +416,20 @@ public class StatsDisplayCanvas extends Canvas { if (draw) { int[] gridLine = new int[] { - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT, - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER }; gc.drawPolyline(gridLine); } } } + // Save the Zero hour for later if (hour == 0) { - dateLocationList.add((int) (GRAPH_BORDER + (i - startMillis) - / millisPerPixelX)); + dateLocationList.add(Math.round(GRAPH_BORDER + + (i - startMillis) / millisPerPixelX)); if (!dateList.contains(cal.getTime())) { dateList.add(cal.getTime()); } @@ -406,22 +437,28 @@ public class StatsDisplayCanvas extends Canvas { buffer.setLength(0); // Clear the buffer int y = GRAPH_BORDER + GRAPH_HEIGHT + 20; int hr = cal.get(Calendar.HOUR_OF_DAY); + int minute = cal.get(Calendar.MINUTE); + + // Draw the tick marks if ((numHours <= 24) || (hour % 6 == 0 && numHours <= 168)) { if (numHours <= 3) { - for (int j = 0; j < 60; j += 15) { + for (int j = 0; j < TimeUtil.MINUTES_PER_HOUR; j += 15) { + buffer.setLength(0); - int x = (int) (GRAPH_BORDER + (i - startMillis + j - * TimeUtil.MILLIS_PER_MINUTE) + int x = Math.round(GRAPH_BORDER + + (i - startMillis + j + * TimeUtil.MILLIS_PER_MINUTE) / millisPerPixelX); if (numHours == 1 || (numHours == 3 && (j == 0 || j == 30))) { String hrStr = (hr < 10) ? ZERO.concat(String .valueOf(hr)) : String.valueOf(hr); - if (j == 0) { + if (minute == 0) { buffer.append(hrStr).append(COLON) .append(MINUTE_00); } else { - buffer.append(hrStr).append(COLON).append(j); + buffer.append(hrStr).append(COLON) + .append(minute); } int adjustment = buffer.length() * fontAveWidth / 2 - 1; @@ -429,30 +466,46 @@ public class StatsDisplayCanvas extends Canvas { if (callback.drawGridLines()) { int[] gridLineArray = { - (int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE - * j) - / millisPerPixelX), + Math.round(GRAPH_BORDER + + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE + * j) / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT, - (int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE - * j) - / millisPerPixelX), + Math.round(GRAPH_BORDER + + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE + * j) / millisPerPixelX), GRAPH_BORDER }; + if (hr == 0 && minute == 0) { + gc.setLineWidth(3); + } gc.drawPolyline(gridLineArray); + gc.setLineWidth(1); + } + minute += 15; + // Roll the minutes and hours, account for rolling + // to the next hour/minute + if (minute >= TimeUtil.MINUTES_PER_HOUR) { + minute = 0; + hr++; + if (hr == TimeUtil.HOURS_PER_DAY) { + hr = 0; + } } } + + // Minor tick marks int[] minorTickArray = { - (int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE - * j) - / millisPerPixelX), + Math.round(GRAPH_BORDER + + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE + * j) / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT, - (int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE - * j) - / millisPerPixelX), + Math.round(GRAPH_BORDER + + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE + * j) / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT + height - 5 }; gc.drawPolyline(minorTickArray); } } else { - int x = (int) (GRAPH_BORDER + (i - startMillis) + int x = Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX); String hrStr = (hr < 10) ? ZERO.concat(String.valueOf(hr)) : String.valueOf(hr); @@ -462,13 +515,13 @@ public class StatsDisplayCanvas extends Canvas { if (callback.drawGridLines()) { if ((numHours == 24 && hr % 6 == 0) - || (numHours == 168 && hr == 0)) { + || (numHours == TimeUtil.HOURS_PER_WEEK && hr == 0)) { int[] gridLineArray = { - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT, - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER }; gc.setLineWidth(1); gc.drawPolyline(gridLineArray); @@ -477,7 +530,7 @@ public class StatsDisplayCanvas extends Canvas { } } } else if (numHours == 336 && hour == 0) { - int x = (int) (GRAPH_BORDER + (i - startMillis) + int x = Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX); buffer.append(cal.get(Calendar.MONTH) + 1); buffer.append("/"); @@ -489,10 +542,10 @@ public class StatsDisplayCanvas extends Canvas { // show every other line if (showLine) { int[] gridLineArray = { - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT, - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER }; gc.setLineWidth(1); gc.drawPolyline(gridLineArray); @@ -503,7 +556,7 @@ public class StatsDisplayCanvas extends Canvas { } else if (numHours == 720) { if (cal.get(Calendar.DAY_OF_MONTH) % 2 == 0 && hour == 0) { - int x = (int) (GRAPH_BORDER + (i - startMillis) + int x = Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX); buffer.append(cal.get(Calendar.MONTH) + 1); buffer.append("/"); @@ -513,10 +566,10 @@ public class StatsDisplayCanvas extends Canvas { if (callback.drawGridLines()) { if (showLine) { int[] gridLineArray = { - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER + GRAPH_HEIGHT, - (int) (GRAPH_BORDER + (i - startMillis) + Math.round(GRAPH_BORDER + (i - startMillis) / millisPerPixelX), GRAPH_BORDER }; gc.setLineWidth(1); gc.drawPolyline(gridLineArray); @@ -556,7 +609,7 @@ public class StatsDisplayCanvas extends Canvas { /** * Draw the Y axis. - * + * * @param gc * The Graphics Context */ @@ -568,14 +621,21 @@ public class StatsDisplayCanvas extends Canvas { gc.drawPolyline(yAxis); Map groupSettings = callback.getGroupSettings(); - + GraphData graphData = callback.getGraphData(); double minVal = graphData.getMinValue(groupSettings.keySet(), view); double maxVal = graphData.getMaxValue(groupSettings.keySet(), view); + if (view != DataView.COUNT) { + UnitUtils uu = callback.getUnitUtils(); + minVal = uu.convertValue(minVal); + maxVal = uu.convertValue(maxVal); + } + + setScaleValues(minVal, maxVal); + int numberTicks = 4; double inc = 5; double minScaleVal = 0; double maxScaleVal = 10; - scalingManager = new ScaleManager(minVal, maxVal); numberTicks = scalingManager.getMajorTickCount(); inc = scalingManager.getMajorTickIncrement(); @@ -607,16 +667,18 @@ public class StatsDisplayCanvas extends Canvas { /** * Draw the YAxis label. - * + * * @param gc * The Graphics Context */ private void drawYAxisLabel(GC gc) { - String unit = this.graphData.getDisplayUnit(); + GraphData graphData = callback.getGraphData(); + String unit = graphData.getDisplayUnit(); StringBuilder yAxisLabel = new StringBuilder(graphTitle); - if (unit != null && !unit.equalsIgnoreCase(COUNT) && unit.length() > 0 - && !view.equals(DataViewUtils.DataView.COUNT.getView())) { + if (isCount(unit)) { + yAxisLabel.append(" Counts"); + } else { yAxisLabel.append(" (").append(unit).append(")"); } @@ -637,9 +699,13 @@ public class StatsDisplayCanvas extends Canvas { t.dispose(); } + private boolean isCount(String unit) { + return view.equals(DataView.COUNT) || COUNT.equalsIgnoreCase(unit); + } + /** * Draw the data on the canvas. - * + * * @param gc * The Graphics Context */ @@ -647,6 +713,8 @@ public class StatsDisplayCanvas extends Canvas { double maxScaleVal = scalingManager.getMaxScaleValue(); double minScaleVal = scalingManager.getMinScaleValue(); Map groupSettings = callback.getGroupSettings(); + UnitUtils uu = callback.getUnitUtils(); + GraphData graphData = callback.getGraphData(); for (String key : graphData.getKeysWithData()) { if (groupSettings.containsKey(key)) { @@ -672,30 +740,27 @@ public class StatsDisplayCanvas extends Canvas { int lastYpix = -999; for (DataPoint point : dataList) { long x = point.getX(); - double y; + double y = point.getValue(view); - if (view.equals(DataViewUtils.DataView.AVG - .getView())) { - y = point.getAvg(); - } else if (view.equals(DataViewUtils.DataView.MIN - .getView())) { - y = point.getMin(); - } else if (view.equals(DataViewUtils.DataView.MAX - .getView())) { - y = point.getMax(); - } else if (view.equals(DataViewUtils.DataView.SUM - .getView())) { - y = point.getSum(); - } else { - y = point.getCount(); + if (view != DataView.COUNT) { + y = uu.convertValue(y); } + + int xPix = 0; int yPix = y2pixel(minScaleVal, maxScaleVal, y); - int xPix = (int) ((x - startMillis) - / millisPerPixelX + GRAPH_BORDER); + + long diff = x - startMillis; + if (diff == 0) { + xPix = GRAPH_BORDER; + } else { + xPix = Math + .round((diff / millisPerPixelX + GRAPH_BORDER)); + } if (xPix > GRAPH_BORDER + GRAPH_WIDTH) { - break; + continue; } + pointList.add(xPix); pointList.add(yPix); Rectangle rect = new Rectangle(xPix - 3, yPix - 3, @@ -710,6 +775,7 @@ public class StatsDisplayCanvas extends Canvas { lastYpix = yPix; } + // Draw each rectangle for (int i = 0; i < rectangleMap.get(key).size(); i++) { Rectangle rect = rectangleMap.get(key).get(i); gc.setForeground(color); @@ -727,7 +793,7 @@ public class StatsDisplayCanvas extends Canvas { /** * Y Value to pixel conversion. - * + * * @param yMin * The smallest y value * @param yMax @@ -739,12 +805,12 @@ public class StatsDisplayCanvas extends Canvas { private int y2pixel(double yMin, double yMax, double y) { double yDiff = yMax - yMin; double yValue = (GRAPH_HEIGHT / yDiff) * (y - yMin); - return (int) (GRAPH_HEIGHT - Math.round(yValue) + GRAPH_BORDER); + return Math.round(GRAPH_HEIGHT - Math.round(yValue) + GRAPH_BORDER); } /** * Mouse move event hanler. - * + * * @param e * MouseEvent object */ @@ -758,6 +824,8 @@ public class StatsDisplayCanvas extends Canvas { if (graphData == null) { return; } + + UnitUtils uu = callback.getUnitUtils(); for (String key : graphData.getKeys()) { int idx = 0; if (rectangleMap.containsKey(key)) { @@ -771,7 +839,24 @@ public class StatsDisplayCanvas extends Canvas { sb.append(key).append(colon); DataPoint point = graphData.getStatsData(key) .getData().get(idx); - sb.append(point.getSampleText(view)); + double value = point.getValue(view); + + if (!view.equals(DataView.COUNT)) { + if (uu.getUnitType() == UnitTypes.DATA_SIZE) { + value = uu.convertDataSizeValue( + DataSizeUnit.BYTE, value); + } else if (uu.getUnitType() == UnitTypes.TIME) { + value = uu.convertTimeValue( + TimeConversion.MS, (long) value); + } + } + + SimpleDateFormat dateFormat = titleDateFormat.get(); + DecimalFormat decimalFormat = decFormat.get(); + + sb.append(dateFormat.format(new Date(point.getX()))) + .append("Z, "); + sb.append(decimalFormat.format(value)); } } idx++; @@ -790,9 +875,102 @@ public class StatsDisplayCanvas extends Canvas { } } + private void setScaleValues(double minVal, double maxVal) { + scalingManager = new ScaleManager(minVal, maxVal); + } + + private void handleMouseDownEvent(MouseEvent e) { + if (e.button == 3) { + GraphData graphData = callback.getGraphData(); + if (graphData == null) { + return; + } + + int x = e.x; + int y = e.y; + List keyList = new ArrayList(); + for (String key : graphData.getKeys()) { + if (rectangleMap.containsKey(key)) { + for (Rectangle rect : rectangleMap.get(key)) { + if (callback.getGroupSettings().containsKey(key)) { + // if true then data are on the graph + if (rect.contains(x, y)) { + keyList.add(key); + } + } + } + } + } + + if (!keyList.isEmpty()) { + showPopup(keyList); + } + } + } + + private void showPopup(final List inputList) { + // Remove the tooltip if it is up + if (tooltip != null && !tooltip.isDisposed()) { + tooltip.dispose(); + } + + // Remove any duplicate entries + Set set = new HashSet(inputList); + final List keyList = new ArrayList(set); + Collections.sort(keyList); + + Menu menu = new Menu(this.getShell(), SWT.POP_UP); + + if (keyList.size() == 1) { + MenuItem selectAll = new MenuItem(menu, SWT.NONE); + selectAll.setText("Hide " + keyList.get(0)); + selectAll.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + handleHide(keyList); + } + }); + } else if (keyList.size() > 1) { + MenuItem hideAll = new MenuItem(menu, SWT.NONE); + hideAll.setText("Hide All Data At Point"); + hideAll.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + handleHide(keyList); + } + }); + + new MenuItem(menu, SWT.SEPARATOR); + + MenuItem hideGraphDlgMI = new MenuItem(menu, SWT.NONE); + hideGraphDlgMI.setText("Hide Graph Lines..."); + hideGraphDlgMI.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + showHideDlg(keyList); + } + }); + } + + // We need to make the menu visible + menu.setVisible(true); + } + + private void handleHide(List keyList) { + groupCallback.setItemsOff(keyList); + redraw(); + } + + private void showHideDlg(List keyList) { + if (hideDlg == null || hideDlg.isDisposed()) { + this.hideDlg = new HideDlg(getShell(), keyList, groupCallback); + } + hideDlg.open(); + } + /** * Show the "tooltip" mouseover. - * + * * @param parent * @param x * @param y @@ -824,7 +1002,7 @@ public class StatsDisplayCanvas extends Canvas { /* * (non-Javadoc) - * + * * @see org.eclipse.swt.widgets.Widget#dispose() */ @Override @@ -836,20 +1014,20 @@ public class StatsDisplayCanvas extends Canvas { } /** - * Set the graph data. - * - * @param graphData - * The GraphData object + * @param view + * The view type */ - public void setGraphData(GraphData graphData) { - this.graphData = graphData; + public void setView(DataView view) { + this.view = view; } /** - * Set the view type. - * @param view The view type + * Set the group selection callback. + * + * @param groupCallback + * The group callback */ - public void setView(String view) { - this.view = view; + public void setCallback(IGroupSelection groupCallback) { + this.groupCallback = groupCallback; } } diff --git a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsGraphDlg.java b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsGraphDlg.java index 1a9e209d87..172f9daba3 100644 --- a/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsGraphDlg.java +++ b/cave/com.raytheon.uf.viz.stats/src/com/raytheon/uf/viz/stats/ui/StatsGraphDlg.java @@ -20,24 +20,21 @@ package com.raytheon.uf.viz.stats.ui; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Menu; @@ -48,7 +45,8 @@ import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.stats.GraphDataRequest; import com.raytheon.uf.common.stats.GraphDataResponse; import com.raytheon.uf.common.stats.data.GraphData; -import com.raytheon.uf.common.stats.util.DataViewUtils; +import com.raytheon.uf.common.stats.util.DataView; +import com.raytheon.uf.common.stats.util.UnitUtils; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -61,17 +59,19 @@ import com.raytheon.viz.ui.widgets.duallist.ButtonImages.ButtonImage; /** * The Graph Data Structure. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Oct 3, 2012     728     mpduff      Initial creation
- *
+ * Oct 03, 2012     728    mpduff      Initial creation.
+ * Jan 17, 2013    1357    mpduff      Add ability to change units.
+ * Jan 18, 2013    1386    mpduff      Change menu text.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -101,8 +101,8 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** Menu bar */ private Menu menuBar; - /** Save Menu Item */ - private MenuItem saveMI; + // /** Save Menu Item */ + // private MenuItem saveMI; /** Exit Menu item */ private MenuItem exitMI; @@ -143,9 +143,17 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** Data view combo */ private Combo viewCombo; + /** Menu item map */ + private final Map menuItemMap = new HashMap(); + + /** The currently displayed unit */ + private String displayUnit; + + private UnitUtils unitUtils; + /** * Constructor. - * + * * @param parent * Parent Shell * @param callback @@ -204,6 +212,8 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, groupComp.setLayout(gl); groupComp.setLayoutData(gd); + displayCanvas.setCallback(groupComp); + gd = new GridData(SWT.FILL, SWT.DEFAULT, false, true); gl = new GridLayout(2, false); Composite ctrlComp = new Composite(leftComp, SWT.NONE); @@ -220,11 +230,11 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, graphLabel.setText("Graph: "); List viewList = new ArrayList(); - viewList.add(DataViewUtils.DataView.AVG.getView()); - viewList.add(DataViewUtils.DataView.MIN.getView()); - viewList.add(DataViewUtils.DataView.MAX.getView()); - viewList.add(DataViewUtils.DataView.SUM.getView()); - viewList.add(DataViewUtils.DataView.COUNT.getView()); + viewList.add(DataView.AVG.getView()); + viewList.add(DataView.MIN.getView()); + viewList.add(DataView.MAX.getView()); + viewList.add(DataView.SUM.getView()); + viewList.add(DataView.COUNT.getView()); gd = new GridData(SWT.LEFT, SWT.CENTER, true, false); viewCombo = new Combo(dataComp, SWT.READ_ONLY); @@ -314,15 +324,15 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, Menu fileMenu = new Menu(menuBar); fileMenuItem.setMenu(fileMenu); - saveMI = new MenuItem(fileMenu, SWT.NONE); - saveMI.setText("&Save\tCtrl+S"); - saveMI.setAccelerator(SWT.CTRL + 'S'); - saveMI.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - saveGraph(); - } - }); + // saveMI = new MenuItem(fileMenu, SWT.NONE); + // saveMI.setText("&Save Graph Image\tCtrl+S"); + // saveMI.setAccelerator(SWT.CTRL + 'S'); + // saveMI.addSelectionListener(new SelectionAdapter() { + // @Override + // public void widgetSelected(SelectionEvent event) { + // saveGraph(); + // } + // }); exitMI = new MenuItem(fileMenu, SWT.NONE); exitMI.setText("&Quit\tCtrl+Q"); @@ -371,11 +381,63 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, displayCanvas.redraw(); } }); + + // Set up the display units menu choices + MenuItem unitsMI = new MenuItem(graphMenu, SWT.CASCADE); + unitsMI.setText("Display Units"); + + unitUtils = new UnitUtils(graphData.getEventType(), + graphData.getDataType()); + String displayUnit = graphData.getDisplayUnit(); + unitUtils.setUnitType(displayUnit); + unitUtils.setDisplayUnit(displayUnit); + Set units = unitUtils.getUnitOptions(); + + Menu unitsMenu = new Menu(graphMenu); + unitsMI.setMenu(unitsMenu); + + for (String unit : units) { + MenuItem mi = new MenuItem(unitsMenu, SWT.CHECK); + mi.setText(unit); + if (unit.equals(graphData.getDisplayUnit())) { + mi.setSelection(true); + } + mi.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + handleUnitsSelection(e); + } + }); + + menuItemMap.put(unit, mi); + } + } + + /** + * Handle the unit selection event. + * + * @param e + * The selection event + */ + private void handleUnitsSelection(SelectionEvent e) { + MenuItem m = (MenuItem) e.getSource(); + for (Entry es : menuItemMap.entrySet()) { + MenuItem mi = es.getValue(); + if (es.getKey().equals(m.getText())) { + m.setSelection(true); + displayUnit = m.getText(); + unitUtils.setDisplayUnit(displayUnit); + graphData.setDisplayUnit(displayUnit); + displayCanvas.redraw(); + } else { + mi.setSelection(false); + } + } } /** * Create the canvas. - * + * * @param comp * Composite holding the canvas */ @@ -395,7 +457,7 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** * Set the GraphData object. - * + * * @param graphData */ public void setGraphData(GraphData graphData) { @@ -412,7 +474,7 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** * Set the title. - * + * * @param title */ public void setTitle(String title) { @@ -421,66 +483,66 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** * Set the graph title. - * + * * @param graphTitle */ public void setGraphTitle(String graphTitle) { this.graphTitle = graphTitle; } - /** - * Open a file dialog for saving the canvas. - */ - private void saveGraph() { - FileDialog dialog = new FileDialog(shell, SWT.SAVE); - String filename = dialog.open(); - if (filename == null) { - return; - } - saveCanvas(filename); - } + // /** + // * Open a file dialog for saving the canvas. + // */ + // private void saveGraph() { + // FileDialog dialog = new FileDialog(shell, SWT.SAVE); + // String filename = dialog.open(); + // if (filename == null) { + // return; + // } + // saveCanvas(filename); + // } - /** - * Captures the canvas and saves the result into a file in a format - * determined by the filename extension . - * - * @param control - * The control to save - * @param fileName - * The name of the image to be saved - */ - public void saveCanvas(String filename) { - StringBuilder sb = new StringBuilder(); - Display display = displayCanvas.getDisplay(); - Image image = new Image(display, displayCanvas.getBounds().width, - displayCanvas.getBounds().height); - GC gc = new GC(image); - - displayCanvas.drawCanvas(gc); - - /* Default to PNG */ - int style = SWT.IMAGE_PNG; - - if ((filename.endsWith(".jpg") == true) || filename.endsWith("jpeg")) { - style = SWT.IMAGE_JPEG; - } else if (filename.endsWith(".bmp") == true) { - style = SWT.IMAGE_BMP; - } else { - filename += ".png"; - } - - ImageLoader loader = new ImageLoader(); - loader.data = new ImageData[] { image.getImageData() }; - loader.save(filename, style); - - sb.setLength(0); - image.dispose(); - gc.dispose(); - } + // /** + // * Captures the canvas and saves the result into a file in a format + // * determined by the filename extension . + // * + // * @param control + // * The control to save + // * @param fileName + // * The name of the image to be saved + // */ + // public void saveCanvas(String filename) { + // StringBuilder sb = new StringBuilder(); + // Display display = displayCanvas.getDisplay(); + // Image image = new Image(display, displayCanvas.getBounds().width, + // displayCanvas.getBounds().height); + // GC gc = new GC(image); + // + // displayCanvas.drawCanvas(gc); + // + // /* Default to PNG */ + // int style = SWT.IMAGE_PNG; + // + // if ((filename.endsWith(".jpg") == true) || filename.endsWith("jpeg")) { + // style = SWT.IMAGE_JPEG; + // } else if (filename.endsWith(".bmp") == true) { + // style = SWT.IMAGE_BMP; + // } else { + // filename += ".png"; + // } + // + // ImageLoader loader = new ImageLoader(); + // loader.data = new ImageData[] { image.getImageData() }; + // loader.save(filename, style); + // + // sb.setLength(0); + // image.dispose(); + // gc.dispose(); + // } /** * Request the graph be redrawn with a new time range. - * + * * @param parameter * The amount of time to move */ @@ -516,7 +578,6 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, default: return; } - GraphDataRequest request = new GraphDataRequest(); request.setGrouping(this.groupList); request.setCategory(this.category); @@ -525,7 +586,7 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, request.setField(dataTypeID); TimeRange newTimeRange = new TimeRange(newStart, newEnd); request.setTimeRange(newTimeRange); - request.setTimeStep(5); + request.setTimeStep((int) graphData.getTimeStep()); try { GraphDataResponse response = (GraphDataResponse) ThriftClient .sendRequest(request); @@ -544,7 +605,6 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, } this.graphData = localGraphData; - this.displayCanvas.setGraphData(graphData); this.displayCanvas.redraw(); } catch (VizException e) { this.statusHandler.handle(Priority.ERROR, "Error Requesting Data", @@ -556,7 +616,8 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, * Handler for data view combo box change. */ private void handleDataViewChange() { - String view = viewCombo.getText(); + String viewStr = viewCombo.getText(); + DataView view = DataView.fromString(viewStr); this.displayCanvas.setView(view); this.displayCanvas.redraw(); } @@ -596,7 +657,7 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** * Set the groups. - * + * * @param groupList * List of groups */ @@ -606,7 +667,7 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** * Set the category. - * + * * @param category */ public void setCategory(String category) { @@ -615,7 +676,7 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** * Set the event type. - * + * * @param typeID */ public void setEventType(String typeID) { @@ -624,10 +685,18 @@ public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay, /** * Set the data type id. - * + * * @param dataTypeID */ public void setDataType(String dataTypeID) { this.dataTypeID = dataTypeID; } + + /** + * {@inheritDoc} + */ + @Override + public UnitUtils getUnitUtils() { + return this.unitUtils; + } } diff --git a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java index 7a7b439666..f2a2ff1134 100644 --- a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java +++ b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java @@ -55,9 +55,6 @@ import com.raytheon.uf.viz.thinclient.localization.LocalizationCachePersistence; import com.raytheon.uf.viz.thinclient.localization.ThinClientLocalizationInitializer; import com.raytheon.uf.viz.thinclient.preferences.ThinClientPreferenceConstants; import com.raytheon.uf.viz.thinclient.refresh.TimedRefresher; -import com.raytheon.viz.alerts.jobs.AutoUpdater; -import com.raytheon.viz.alerts.jobs.MenuUpdater; -import com.raytheon.viz.alerts.observers.ProductAlertObserver; import com.raytheon.viz.ui.personalities.awips.AbstractCAVEComponent; import com.raytheon.viz.ui.personalities.awips.CAVE; @@ -188,8 +185,11 @@ public class ThinClientComponent extends CAVE implements IThinClientComponent { @Override protected void initializeObservers() { ThinClientNotificationManagerJob.getInstance(); - ProductAlertObserver.addObserver(null, new MenuUpdater()); - ProductAlertObserver.addObserver(null, new AutoUpdater()); + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + if (store.getBoolean(ThinClientPreferenceConstants.P_DISABLE_JMS) == false) { + // JMS Enabled, register product alerts + registerProductAlerts(); + } } public void stopComponent() { diff --git a/cave/com.raytheon.uf.viz.ui.menus/src/com/raytheon/uf/viz/ui/menus/widgets/BundleContributionItem.java b/cave/com.raytheon.uf.viz.ui.menus/src/com/raytheon/uf/viz/ui/menus/widgets/BundleContributionItem.java index f111585083..032600742c 100644 --- a/cave/com.raytheon.uf.viz.ui.menus/src/com/raytheon/uf/viz/ui/menus/widgets/BundleContributionItem.java +++ b/cave/com.raytheon.uf.viz.ui.menus/src/com/raytheon/uf/viz/ui/menus/widgets/BundleContributionItem.java @@ -56,8 +56,11 @@ import com.raytheon.uf.viz.core.procedures.BundleUtil.BundleDataItem; import com.raytheon.uf.viz.core.rsc.URICatalog; import com.raytheon.uf.viz.core.rsc.URICatalog.IURIRefreshCallback; import com.raytheon.uf.viz.ui.menus.xml.BundleMenuContribution; -import com.raytheon.viz.ui.MenuLoader; -import com.raytheon.viz.ui.actions.LoadSerializedXml; +import com.raytheon.viz.ui.BundleLoader; +import com.raytheon.viz.ui.BundleLoader.BundleInfoType; +import com.raytheon.viz.ui.BundleProductLoader; +import com.raytheon.viz.ui.UiUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; /** * Provides an Eclipse menu contribution that loads a bundle, and is decorated @@ -345,15 +348,19 @@ public class BundleContributionItem extends ContributionItem { private void loadBundle(Event event) { try { + Bundle bundle = BundleLoader.getBundle( + this.menuContribution.xml.bundleFile, substitutions, + BundleInfoType.FILE_LOCATION); + AbstractEditor editor = UiUtil.createOrOpenEditor( + this.menuContribution.xml.editorType, bundle.getDisplays()); + BundleLoader loader; if (this.menuContribution.xml.fullBundleLoad == null || this.menuContribution.xml.fullBundleLoad == false) { - MenuLoader.loadProduct(this.menuContribution.xml.editorType, - this.menuContribution.xml.bundleFile, substitutions); + loader = new BundleProductLoader(editor, bundle); } else { - LoadSerializedXml.loadTo(PathManagerFactory.getPathManager() - .getStaticFile(this.menuContribution.xml.bundleFile), - substitutions); + loader = new BundleLoader(editor, bundle); } + loader.schedule(); if (this.menuContribution.xml.command != null) { ICommandService service = (ICommandService) PlatformUI diff --git a/cave/com.raytheon.viz.alerts/src/com/raytheon/viz/alerts/observers/ProductAlertObserver.java b/cave/com.raytheon.viz.alerts/src/com/raytheon/viz/alerts/observers/ProductAlertObserver.java index c83bf232d9..7fc148a79f 100644 --- a/cave/com.raytheon.viz.alerts/src/com/raytheon/viz/alerts/observers/ProductAlertObserver.java +++ b/cave/com.raytheon.viz.alerts/src/com/raytheon/viz/alerts/observers/ProductAlertObserver.java @@ -19,6 +19,7 @@ **/ package com.raytheon.viz.alerts.observers; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -306,58 +307,49 @@ public class ProductAlertObserver implements INotificationObserver { PracticeDataURINotificationMessage uriMsg = (PracticeDataURINotificationMessage) payLoad; dataURIs = uriMsg.getDataURIs(); } - for (int i = 0; i < dataURIs.length; ++i) { - String str = dataURIs[i]; - processDataURI(str); - } - - startWrappers(); - - if (dataURIs != null && dataURIs.length > 0) { - alertsProcessed += dataURIs.length; - } - - long curTime = System.currentTimeMillis(); - if (curTime - ALERT_LOG_INTERVAL > lastLogTime) { - if (alertsProcessed > 0) { - statusHandler.handle(Priority.VERBOSE, "Processed " - + alertsProcessed + " alerts in the last " - + ((curTime - lastLogTime) / 60000) - + " minutes"); - alertsProcessed = 0; - } - lastLogTime = curTime; - } + processDataURIs(Arrays.asList(dataURIs)); } } } - public static void processDerivedAlerts(Collection datauris) { - for (String datauri : datauris) { - getInstance().processDataURI(datauri); + /** + * Processes the DataURIs as alert messages + * + * @param datauris + */ + public static void processDataURIAlerts(Collection datauris) { + getInstance().processDataURIs(datauris); + } + + private synchronized void processDataURIs(Collection dataURIs) { + for (String str : dataURIs) { + processDataURI(str); + } + + startWrappers(); + + if (dataURIs != null && dataURIs.size() > 0) { + alertsProcessed += dataURIs.size(); + } + + long curTime = System.currentTimeMillis(); + if (curTime - ALERT_LOG_INTERVAL > lastLogTime) { + if (alertsProcessed > 0) { + statusHandler.handle(Priority.VERBOSE, "Processed " + + alertsProcessed + " alerts in the last " + + ((curTime - lastLogTime) / 60000) + " minutes"); + alertsProcessed = 0; + } + lastLogTime = curTime; } - getInstance().startWrappers(); } private void processDataURI(String datauri) { if (datauri == null) return; try { - Map attribs; - try { - attribs = RecordFactory.getInstance().loadMapFromUri(datauri); - - } catch (NoPluginException e) { - // ignore, if we hit this it means we received an alert from - // edex about ingested data, but viz doesn't have the necessary - // plugins to do anything with it - return; - } catch (Exception e1) { - statusHandler.handle(Priority.WARN, e1.getLocalizedMessage(), - e1); - return; - } - + Map attribs = RecordFactory.getInstance() + .loadMapFromUri(datauri); AlertMessage am = new AlertMessage(); am.dataURI = datauri; am.decodedAlert = Collections.unmodifiableMap(attribs); @@ -379,11 +371,12 @@ public class ProductAlertObserver implements INotificationObserver { sendToObserver(obs, am); } } - - } catch (RuntimeException e) { - statusHandler - .handle(Priority.PROBLEM, "Error preparing updates", e); - + } catch (NoPluginException e) { + // ignore, if we hit this it means we received an alert from + // edex about ingested data, but viz doesn't have the necessary + // plugins to do anything with it + } catch (Exception e1) { + statusHandler.handle(Priority.WARN, e1.getLocalizedMessage(), e1); } } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/BaseGfePyController.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/BaseGfePyController.java index 3305246d2d..e02600cd53 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/BaseGfePyController.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/BaseGfePyController.java @@ -51,6 +51,8 @@ import com.raytheon.viz.gfe.smartscript.FieldDefinition; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Nov 10, 2008 njensen Initial creation + * Jan 18, 2013 njensen Added garbageCollect() + * * * * @author njensen @@ -354,4 +356,20 @@ public abstract class BaseGfePyController extends PythonScript implements execute("addModule", INTERFACE, argMap); } + /** + * Runs the python garbage collector. This should be run at the end of a + * procedure or tool in case the custom python used tk. If the python used + * tk and it is not garbage collected, errors about invalid threads may + * occur when the garbage collector runs in another python interpreter. + */ + public void garbageCollect() { + try { + jep.eval("import gc"); + jep.eval("gc.collect()"); + } catch (JepException e) { + statusHandler.handle(Priority.PROBLEM, + "Error garbage collecting GFE python interpreter", e); + } + } + } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/DbParm.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/DbParm.java index 688b4d7f7c..aa9d2efe9c 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/DbParm.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/DbParm.java @@ -73,6 +73,7 @@ import com.raytheon.viz.gfe.core.griddata.IGridData; * to use IFPClient * 02/23/12 #346 dgilling Implement a dispose method. * 03/01/12 #346 dgilling Re-order dispose method. + * 01/21/12 #1504 randerso Cleaned up old debug logging to improve performance * * * @@ -411,6 +412,7 @@ public class DbParm extends Parm { // normal mode if (normal) { Arrays.sort(grids); + // Now replace the existing grids with the new ones replaceGrids(affectedTimeRange, grids); @@ -621,6 +623,7 @@ public class DbParm extends Parm { success &= allSaved; } + // if any pending saves if (sgr.size() > 0) { if (doSave(sgr)) { @@ -630,13 +633,7 @@ public class DbParm extends Parm { } else { success = false; } - } - - // if any pending saves - if (sgr.size() > 0) { - if (!doSave(sgr)) { - success = false; - } + pendingUnlocks.clear(); } if (success) { @@ -757,10 +754,10 @@ public class DbParm extends Parm { List lreq = new ArrayList(timesToSave.size()); for (int i = 0; i < timesToSave.size(); i++) { - String msg = "Reverting " + getParmID() + " tr=" - + timesToSave.get(i); - statusHandler.handle(Priority.DEBUG, msg, new Exception("Debug: " - + msg)); + // String msg = "Reverting " + getParmID() + " tr=" + // + timesToSave.get(i); + // statusHandler.handle(Priority.DEBUG, msg, new Exception("Debug: " + // + msg)); boolean success = true; IGridData[] grids = null; diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/gridmanager/GridCanvas.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/gridmanager/GridCanvas.java index fb3813d64f..ceebd780f3 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/gridmanager/GridCanvas.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/gridmanager/GridCanvas.java @@ -24,9 +24,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; -import java.util.HashMap; +import java.util.Iterator; import java.util.List; -import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -107,8 +106,11 @@ import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; * Apr 7, 2009 randerso Initial creation * Jun 3, 2011 8919 rferrel Determine grid's VisMode based * on imageOnEdit - * 08/20/2012 #1082 randerso Moved calcStepTimes to AbstractParmManager for + * 08/20/2012 #1082 randerso Moved calcStepTimes to AbstractParmManager for * use in PngWriter + * 11/30/2012 #1328 mschenke Made GFE use descriptor for time matching + * and time storage and manipulation + * 01/22/2013 #1518 randerso Removed use of Map with Parms as keys * * * @@ -256,8 +258,6 @@ public class GridCanvas extends Canvas implements IMessageClient { private ArrayList gridBarList; - private Map parmToGridBar; - private Rectangle selection; private MenuManager menuMgr; @@ -294,7 +294,6 @@ public class GridCanvas extends Canvas implements IMessageClient { dataMgr = gridManager.getDataManager(); gridBarList = new ArrayList(); - parmToGridBar = new HashMap(); Parm[] displayedParms = gridManager.getDataManager().getParmManager() .getDisplayedParms(); @@ -684,10 +683,13 @@ public class GridCanvas extends Canvas implements IMessageClient { if (deletions != null) { for (Parm parm : deletions) { - GridBar gridBar = parmToGridBar.remove(parm); - if (gridBar != null) { - gridBarList.remove(gridBar); - gridBar.dispose(); + Iterator iter = gridBarList.iterator(); + while (iter.hasNext()) { + GridBar gridBar = iter.next(); + if (gridBar.getParm().equals(parm)) { + iter.remove(); + gridBar.dispose(); + } } } } @@ -695,11 +697,8 @@ public class GridCanvas extends Canvas implements IMessageClient { if (additions != null) { for (Parm parm : additions) { if (!parm.getGridInfo().isTimeIndependentParm()) { - if (!parmToGridBar.containsKey(parm)) { - GridBar gridBar = new GridBar(this, parm, gridManager); - gridBarList.add(gridBar); - parmToGridBar.put(parm, gridBar); - } + GridBar gridBar = new GridBar(this, parm, gridManager); + gridBarList.add(gridBar); } } } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ifpimage/ImageLegendResource.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ifpimage/ImageLegendResource.java index 9ef5676f0c..da5272e317 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ifpimage/ImageLegendResource.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/ifpimage/ImageLegendResource.java @@ -21,7 +21,6 @@ package com.raytheon.viz.gfe.ifpimage; import java.util.ArrayList; import java.util.Calendar; -import java.util.Collection; import java.util.Formatter; import java.util.HashMap; import java.util.List; @@ -31,6 +30,7 @@ import java.util.TimeZone; import org.eclipse.swt.graphics.RGB; +import com.raytheon.uf.common.dataplugin.gfe.type.Pair; import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.viz.core.RGBColors; @@ -42,7 +42,6 @@ import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; import com.raytheon.viz.core.ColorUtil; import com.raytheon.viz.gfe.Activator; import com.raytheon.viz.gfe.core.DataManager; -import com.raytheon.viz.gfe.core.griddata.IGridData; import com.raytheon.viz.gfe.core.parm.Parm; import com.raytheon.viz.gfe.core.parm.ParmDisplayAttributes.VisMode; import com.raytheon.viz.gfe.rsc.GFELegendResource; @@ -62,6 +61,10 @@ import com.raytheon.viz.gfe.rsc.GFEResource; * Jul 10, 2012 15186 ryu Set legend font * Aug 20, 2012 #1078 dgilling Fix handling of ImageLegend_color * setting. + * Nov 30, 2012 #1328 mschenke Made GFE use descriptor for time matching + * and time storage and manipulation + * Jan 22, 2013 #1518 randerso Removed use of Map with Parms as keys, + * really just needed a list anyway. * * * @@ -100,9 +103,8 @@ public class ImageLegendResource extends GFELegendResource { @Override public LegendEntry[] getLegendData(IDescriptor descriptor) { - Map parmRscMap = new HashMap(); - Collection parms = getLegendOrderedParms(descriptor, parmRscMap); - LegendData[] data = makeLegend(parms, parmRscMap); + List> parms = getLegendOrderedParms(descriptor); + LegendData[] data = makeLegend(parms); LegendEntry[] entries = new LegendEntry[data.length]; for (int i = 0; i < entries.length; ++i) { @@ -113,15 +115,15 @@ public class ImageLegendResource extends GFELegendResource { return entries; } - private LegendData[] makeLegend(Collection parms, - Map parmRscMap) { + private LegendData[] makeLegend(List> parms) { FramesInfo currInfo = descriptor.getFramesInfo(); DataTime curTime = currInfo.getCurrentFrame(); // loop through the grids List legendData = new ArrayList(); - for (Parm parm : parms) { - ResourcePair rp = parmRscMap.get(parm); + for (Pair pair : parms) { + Parm parm = pair.getFirst(); + ResourcePair rp = pair.getSecond(); GFEResource rsc = (GFEResource) rp.getResource(); String parmName = parm.getParmID().getParmName(); ResourceProperties props = rp.getProperties(); @@ -150,7 +152,6 @@ public class ImageLegendResource extends GFELegendResource { // get the units for the time string String units = rsc.getParm().getGridInfo().getUnitString(); - IGridData[] gd = new IGridData[0]; Locale locale = Locale.getDefault(); String lang = getLanguage(); diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/procedures/ProcedureJob.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/procedures/ProcedureJob.java index ab3d246e95..a9b8a5d7c3 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/procedures/ProcedureJob.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/procedures/ProcedureJob.java @@ -56,6 +56,7 @@ import com.raytheon.viz.gfe.jobs.AsyncProgressJob; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Oct 8, 2009 njensen Initial creation + * Jan 18, 2013 1509 njensen Garbage collect after running procedure * * * @@ -395,6 +396,7 @@ public class ProcedureJob extends AbstractQueueJob { statusHandler.handle(Priority.PROBLEM, "Error executing procedure " + procedureName, e); } finally { + controller.garbageCollect(); progressJob.done(pjStatus); } } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFELegendResource.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFELegendResource.java index ce10249422..4431e1be17 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFELegendResource.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFELegendResource.java @@ -23,13 +23,11 @@ import static com.raytheon.viz.gfe.core.parm.ParmDisplayAttributes.VisMode.IMAGE import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.Date; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.TimeZone; import org.eclipse.jface.preference.IPreferenceStore; @@ -37,6 +35,7 @@ import org.eclipse.swt.graphics.RGB; import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; +import com.raytheon.uf.common.dataplugin.gfe.type.Pair; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -65,6 +64,7 @@ import com.raytheon.viz.gfe.PreferenceInitializer; import com.raytheon.viz.gfe.core.DataManager; import com.raytheon.viz.gfe.core.ISpatialDisplayManager; import com.raytheon.viz.gfe.core.griddata.IGridData; +import com.raytheon.viz.gfe.core.msgs.INewModelAvailableListener; import com.raytheon.viz.gfe.core.msgs.Message; import com.raytheon.viz.gfe.core.msgs.Message.IMessageClient; import com.raytheon.viz.gfe.core.msgs.ShowQuickViewDataMsg; @@ -83,13 +83,18 @@ import com.raytheon.viz.ui.input.InputAdapter; * 03/17/2008 chammack Initial Creation. * 08/19/2009 2547 rjpeter Implement Test/Prac database display. * 07/10/2012 15186 ryu Clean up initInternal per Ron + * 11/30/2012 #1328 mschenke Made GFE use descriptor for time matching + * and time storage and manipulation + * 01/22/2013 #1518 randerso Removed use of Map with Parms as keys, + * really just needed a list anyway. * * * @author chammack * @version 1.0 */ public class GFELegendResource extends - AbstractLegendResource implements IMessageClient { + AbstractLegendResource implements + IMessageClient, INewModelAvailableListener { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(GFELegendResource.class); @@ -118,8 +123,6 @@ public class GFELegendResource extends private class GFELegendInputHandler extends InputAdapter { - private boolean inDrag; - ResourcePair mouseDownRsc = null; @Override @@ -158,10 +161,9 @@ public class GFELegendResource extends if (rsc.getResource() instanceof GFEResource) { GFEResource gfeRsc = (GFEResource) rsc .getResource(); - DataManager - .getCurrentInstance() - .getSpatialDisplayManager() - .makeVisible(gfeRsc.getParm(), + GFELegendResource.this.dataManager + .getSpatialDisplayManager().makeVisible( + gfeRsc.getParm(), !props.isVisible(), false); } else { @@ -173,8 +175,7 @@ public class GFELegendResource extends } else if (mouseButton == 2) { if (rsc.getResource() instanceof GFEResource) { GFEResource gfeRsc = (GFEResource) rsc.getResource(); - ISpatialDisplayManager sdm = DataManager - .getCurrentInstance() + ISpatialDisplayManager sdm = GFELegendResource.this.dataManager .getSpatialDisplayManager(); Parm parm = gfeRsc.getParm(); @@ -242,7 +243,6 @@ public class GFELegendResource extends }.run(); } - @SuppressWarnings("unchecked") public GFELegendResource(DataManager dataManager, GFELegendResourceData resourceData, LoadProperties loadProps) { super(resourceData, loadProps); @@ -257,8 +257,6 @@ public class GFELegendResource extends } catch (Exception e) { mode = LegendMode.GRIDS; } - - Message.registerInterest(this, ShowQuickViewDataMsg.class); } protected void addSpaces(StringBuilder sb, int numSpace) { @@ -267,23 +265,6 @@ public class GFELegendResource extends } } - /* - * (non-Javadoc) - * - * @see java.lang.Object#finalize() - */ - @SuppressWarnings("unchecked") - @Override - protected void finalize() throws Throwable { - // FIXME: this needs to be a dispose method. - Message.unregisterInterest(this, ShowQuickViewDataMsg.class); - - if (font != null) { - font.dispose(); - font = null; - } - } - /* * (non-Javadoc) * @@ -319,26 +300,21 @@ public class GFELegendResource extends } /** - * Gets an ordered collection of Parms to display for the legend. + * Gets an ordered list of Parm/ResourcePair pairs to display for the + * legend. * * @param descriptor - * @param parmRscMap - * optional map to create Parm->ResourcePair mapping for parms - * returned * @return */ - protected Collection getLegendOrderedParms(IDescriptor descriptor, - Map parmRscMap) { - List parms = new ArrayList(); + protected List> getLegendOrderedParms( + IDescriptor descriptor) { + List> parms = new ArrayList>(); for (ResourcePair rp : descriptor.getResourceList()) { if (rp.getResource() instanceof GFEResource) { Parm parm = ((GFEResource) rp.getResource()).getParm(); if (qvGrid == null || (qvGrid != null && qvGrid.getParm() == parm)) { - parms.add(parm); - if (parmRscMap != null) { - parmRscMap.put(parm, rp); - } + parms.add(new Pair(parm, rp)); if (qvGrid != null) { break; } @@ -346,8 +322,14 @@ public class GFELegendResource extends } } - Collections.sort(parms); - Collections.reverse(parms); + Collections.sort(parms, new Comparator>() { + + @Override + public int compare(Pair o1, + Pair o2) { + return o2.getFirst().compareTo(o1.getFirst()); + } + }); return parms; } @@ -362,8 +344,7 @@ public class GFELegendResource extends .getActivatedParm(); StringBuilder labelBuilder = new StringBuilder(); - Map parmRscMap = new HashMap(); - Collection parms = getLegendOrderedParms(descriptor, parmRscMap); + List> parms = getLegendOrderedParms(descriptor); Parm qvParm = null; if (qvGrid != null) { qvParm = qvGrid.getParm(); @@ -374,11 +355,12 @@ public class GFELegendResource extends ParmID topoID = dataManager.getTopoManager().getCompositeParmID(); // Topmost resources: GFE Parms - for (Parm parm : parms) { + for (Pair pair : parms) { + Parm parm = pair.getFirst(); ParmID parmId = parm.getParmID(); DatabaseID dbId = parmId.getDbId(); StringBuilder sb = new StringBuilder(); - ResourcePair rp = parmRscMap.get(parm); + ResourcePair rp = pair.getSecond(); GFEResource rsc = (GFEResource) rp.getResource(); LegendData ld = new LegendData(); ResourceProperties props = rp.getProperties(); @@ -435,33 +417,27 @@ public class GFELegendResource extends // get the model name labelBuilder.setLength(0); - labelBuilder.append(dbId.getModelName()); + labelBuilder.append(dbId.getShortModelId()); - boolean iscTyped = false; - if (dataManager.getParmManager().iscMode() - && dbId.equals(dataManager.getParmManager() - .getMutableDatabase())) { + // FIXME this is from A1 and is not consistent with the code in + // getLongestFields - ParmID iscPID = dataManager.getParmManager().getISCParmID( - parmId); - if (iscPID.isValid()) { - // vparms (i.e. temp hazards) can't get here - String iscStr = "+" + iscPID.getDbId().getDbType() - + iscPID.getDbId().getModelName(); - labelBuilder.append(iscStr); - iscTyped = true; - } - } + // if (_showISCMode && _quickViewGrid == GridID() + // && _grids[i].gridID().parm()->parmID().databaseID() == + // _dbss->dataManager()->parmMgr()->mutableDatabase()) + // { + // unsigned int mpos = 0; + // if (modelText.found(' ', mpos)) + // { + // ParmID iscPID = + // _dbss->dataManager()->parmMgr()->getISCParmID( + // _grids[i].gridID().parm()->parmID()); + // TextString iscStr = "+" + iscPID.databaseID().type() + + // iscPID.databaseID().model(); + // modelText.insertBefore(mpos, iscStr); + // } + // } - if (!iscTyped) { - String type = dbId.getDbType(); - if ((type != null) && (type.length() > 0)) { - labelBuilder.append("_"); - labelBuilder.append(type); - } - } - - labelBuilder.append(" (" + dbId.getSiteId() + ")"); sb.append(labelBuilder.toString()); diff = lengths[3] - labelBuilder.length(); addSpaces(sb, diff + 1); @@ -562,16 +538,14 @@ public class GFELegendResource extends * @param descriptor * @return */ - private int[] getLongestFields(Collection parms) { + private int[] getLongestFields(List> parms) { // Iterator rl = descriptor.getResourceList().iterator(); int[] sz = new int[4]; StringBuilder labelBuilder = new StringBuilder(); // synchronized (rl) { // while (rl.hasNext()) { - for (Parm parm : parms) { - // AbstractVizResource resource = rl.next().getResource(); - // if (resource instanceof GFEResource) { - // Parm parm = ((GFEResource) resource).getParm(); + for (Pair pair : parms) { + Parm parm = pair.getFirst(); ParmID parmId = parm.getParmID(); sz[0] = Math.max(sz[0], parmId.getParmName().length()); sz[1] = Math.max(sz[1], parmId.getParmLevel().length()); @@ -580,52 +554,33 @@ public class GFELegendResource extends DatabaseID dbId = parmId.getDbId(); labelBuilder.setLength(0); - labelBuilder.append(dbId.getModelName()); + labelBuilder.append(dbId.getShortModelId()); - boolean iscTyped = false; - if (dataManager.getParmManager().iscMode() - && dbId.equals(dataManager.getParmManager() - .getMutableDatabase())) { + // FIXME this is A1 code and is not consistent with the code in + // getLegendDataGrids - ParmID iscPID = dataManager.getParmManager().getISCParmID( - parmId); - if (iscPID.isValid()) { - // vparms (i.e. temp hazards) can't get here - String iscStr = "+" + iscPID.getDbId().getDbType() - + iscPID.getDbId().getModelName(); - labelBuilder.append(iscStr); - iscTyped = true; - } - } - - if (!iscTyped) { - String type = dbId.getDbType(); - if ((type != null) && (type.length() > 0)) { - labelBuilder.append("_"); - labelBuilder.append(type); - } - } - - labelBuilder.append(" (" + dbId.getSiteId() + ")"); - // TODO: FIXME // if (showIscMode // && ids[i].gridID().parm()->parmID().databaseID() == // _dbss->dataManager()->parmMgr()->mutableDatabase()) // label += "+VISC"; - sz[3] = Math.max(sz[3], labelBuilder.length()); - // } + sz[3] = Math.max(sz[3], labelBuilder.length()); } - // } return sz; } + @SuppressWarnings("unchecked") @Override protected void disposeInternal() { super.disposeInternal(); + + this.dataManager.getParmManager().removeNewModelAvailableListener(this); + Message.unregisterInterest(this, ShowQuickViewDataMsg.class); + if (font != null) { font.dispose(); + font = null; } IDisplayPaneContainer container = getResourceContainer(); if (container != null) { @@ -633,9 +588,14 @@ public class GFELegendResource extends } } + @SuppressWarnings("unchecked") @Override protected void initInternal(IGraphicsTarget target) throws VizException { super.initInternal(target); + + Message.registerInterest(this, ShowQuickViewDataMsg.class); + this.dataManager.getParmManager().addNewModelAvailableListener(this); + int fontNum = 3; if (GFEPreference.contains("SELegend_font")) { fontNum = GFEPreference.getIntPreference("SELegend_font"); @@ -689,4 +649,9 @@ public class GFELegendResource extends } } + @Override + public void newModelAvailable(DatabaseID additions) { + issueRefresh(); + } + } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/DiscreteColorbar.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/DiscreteColorbar.java index 503d3ad132..a504f92471 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/DiscreteColorbar.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/DiscreteColorbar.java @@ -82,7 +82,7 @@ import com.vividsolutions.jts.geom.Coordinate; /** * Implements a colorbar for continuous (scalar and vector) elements - * + * *
  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
@@ -91,11 +91,13 @@ import com.vividsolutions.jts.geom.Coordinate;
  * Aug 20, 2008            dglazesk    Updated for the new ColorMap interface
  * Aug 20, 2012      1079  randerso    Changed to display all discrete values for
  *                                     non-overlapping discretes
- * Jan 9, 2013  15661      ryu         Set font for drawing regular Wx/discrete parm labels.
- * Jan 10, 2013  15548     ryu         Update colorbar when new discrete colormap is selected
- *
+ * Jan  9, 2013     15661  ryu         Set font for drawing regular Wx/discrete parm labels.
+ * Jan 10, 2013     15548  ryu         Update colorbar when new discrete colormap is selected
+ * Jan 23, 2013     #1524  randerso    Fix missing discrete color bar and error when clicking 
+ *                                     on discrete color bar when no grid exists
+ * 
  * 
- * + * * @author chammack * @version 1.0 */ @@ -139,7 +141,7 @@ public class DiscreteColorbar implements IColorBarDisplay, /** * Constructor for the Discrete Color Bar - * + * * @param parm * The parm * @param colorbarResource @@ -162,8 +164,7 @@ public class DiscreteColorbar implements IColorBarDisplay, DataManager dataManager = parm.getDataManager(); ISpatialDisplayManager spatialDisplayManager = dataManager .getSpatialDisplayManager(); - ResourcePair resourcePair = spatialDisplayManager - .getResourcePair(parm); + ResourcePair resourcePair = spatialDisplayManager.getResourcePair(parm); AbstractVizResource resource = resourcePair.getResource(); ColorMapParameters params = resource.getCapability( ColorMapCapability.class).getColorMapParameters(); @@ -172,7 +173,7 @@ public class DiscreteColorbar implements IColorBarDisplay, /* * (non-Javadoc) - * + * * @see com.raytheon.viz.gfe.rsc.colorbar.IColorBarDisplay#dispose() */ @Override @@ -193,7 +194,7 @@ public class DiscreteColorbar implements IColorBarDisplay, /** * Gets the Discrete Color map. - * + * * @return Returns the color map used for the discrete data. */ public static ColorMap getFallbackColorMap() { @@ -202,7 +203,7 @@ public class DiscreteColorbar implements IColorBarDisplay, /* * (non-Javadoc) - * + * * @see * com.raytheon.viz.core.drawables.IRenderable#paint(com.raytheon.viz.core * .IGraphicsTarget, com.raytheon.viz.core.drawables.PaintProperties) @@ -210,7 +211,7 @@ public class DiscreteColorbar implements IColorBarDisplay, @Override public void paint(IGraphicsTarget target, PaintProperties paintProps) throws VizException { - DataTime currentTime = paintProps.getDataTime(); + DataTime currentTime = paintProps.getFramesInfo().getCurrentFrame(); if (parm == null || currentTime == null) { return; } @@ -426,7 +427,7 @@ public class DiscreteColorbar implements IColorBarDisplay, * Labels that do not fit their designated band on the bar will be * truncated. Pickup value text will always be displayed in full, so any * text it overlaps will not be drawn. - * + * * @param target * The graphics target on which to draw * @param colorTable @@ -557,7 +558,7 @@ public class DiscreteColorbar implements IColorBarDisplay, /** * Draws the colorbar once colors and patterns have been decided. - * + * * @param target * The graphics target on which to draw. * @param pixelExtent @@ -657,34 +658,42 @@ public class DiscreteColorbar implements IColorBarDisplay, /* * (non-Javadoc) - * + * * @see * com.raytheon.viz.gfe.rsc.colorbar.IColorBarDisplay#getValueAt(double[], * int) */ @Override public WxValue getValueAt(double[] coord, int mouseButton) { - PixelExtent lastExtent = colorbarResource.getExtent(); - float fractionX = (float) ((coord[0] - lastExtent.getMinX()) / (lastExtent - .getMaxX() - lastExtent.getMinX())); - int index = (int) (gridKeys.size() * fractionX); - if (index >= gridKeys.size()) { - index = gridKeys.size() - 1; - } + WxValue retVal = null; + if (!gridKeys.isEmpty()) { + PixelExtent lastExtent = colorbarResource.getExtent(); + float fractionX = (float) ((coord[0] - lastExtent.getMinX()) / (lastExtent + .getMaxX() - lastExtent.getMinX())); + int index = (int) (gridKeys.size() * fractionX); + if (index >= gridKeys.size()) { + index = gridKeys.size() - 1; + } - switch (parm.getGridInfo().getGridType()) { - case DISCRETE: { - DiscreteWxValue castedVal = (DiscreteWxValue) gridKeys.get(index); - return new DiscreteWxValue(castedVal.getDiscreteKey(), parm); - } - case WEATHER: { - WeatherWxValue castedVal = (WeatherWxValue) gridKeys.get(index); - return new WeatherWxValue(castedVal.getWeatherKey(), parm); - } - default: - throw new IllegalArgumentException( - "getValueAt does not support type: " - + parm.getGridInfo().getGridType()); + switch (parm.getGridInfo().getGridType()) { + case DISCRETE: { + DiscreteWxValue castedVal = (DiscreteWxValue) gridKeys + .get(index); + retVal = new DiscreteWxValue(castedVal.getDiscreteKey(), parm); + break; + } + case WEATHER: { + WeatherWxValue castedVal = (WeatherWxValue) gridKeys.get(index); + retVal = new WeatherWxValue(castedVal.getWeatherKey(), parm); + + break; + } + default: + throw new IllegalArgumentException( + "getValueAt does not support type: " + + parm.getGridInfo().getGridType()); + } } + return retVal; } } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java index 9e5888fdf6..22a6bafaec 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java @@ -28,8 +28,6 @@ import java.util.Set; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; @@ -98,8 +96,10 @@ import com.raytheon.viz.ui.input.InputAdapter; * 05Aug2008 #1405 ebabin Fix fo delta not displaying after first use. * 06/03/2011 #8919 rferrel No longer display color bar when * VisMode is GRAPHIC - * 11/13/20112 #1298 rferrel Changes for non-blocking SetDeltaDialog. + * 11/13/2012 #1298 rferrel Changes for non-blocking SetDeltaDialog. * Changes for non-blocking SetValueDialog. + * 01/23/2013 #1524 randerso Fix error when clicking on discrete color bar when + * no grid exists * * * @@ -175,6 +175,10 @@ public class GFEColorbarResource extends private void setPickup(double[] v, int mouseButton) { WxValue val = colorbarDisplay.getValueAt(v, mouseButton); + if (val == null) { + return; + } + Parm parm = getParm(); if (parm == null) { throw new IllegalStateException("Parm is null from colorbar"); diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/script/SmartToolJob.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/script/SmartToolJob.java index 05dcae6f9f..c154f9439b 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/script/SmartToolJob.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/script/SmartToolJob.java @@ -53,6 +53,7 @@ import com.raytheon.viz.gfe.smarttool.Tool; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jan 19, 2010 njensen Initial creation + * Jan 18, 2013 1509 njensen Garbage collect after running tool * * * @@ -164,6 +165,7 @@ public class SmartToolJob extends AbstractQueueJob { "Error in smart tool", e); throw e; } finally { + python.garbageCollect(); progressJob.done(pjResult); req = request; request = null; diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/GridProductBrowserDataDefinition.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/GridProductBrowserDataDefinition.java index 16a87185fc..f0d46ed512 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/GridProductBrowserDataDefinition.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/GridProductBrowserDataDefinition.java @@ -47,9 +47,12 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.datastructure.DataCubeContainer; +import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizCommunicationException; +import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.level.LevelMappingFactory; import com.raytheon.uf.viz.core.rsc.DisplayType; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; import com.raytheon.uf.viz.core.rsc.ResourceType; import com.raytheon.uf.viz.derivparam.library.DerivParamDesc; import com.raytheon.uf.viz.derivparam.library.DerivedParameterGenerator; @@ -129,6 +132,48 @@ public class GridProductBrowserDataDefinition extends return new GridResourceData(); } + @Override + public void constructResource(String[] selection, ResourceType type) { + GridInventory inventory = getInventory(); + if (inventory == null) { + super.constructResource(selection, type); + return; + } + if (type != null) { + loadProperties.setResourceType(type); + } + HashMap parameters = getProductParameters( + selection, order); + List ensembles = null; + try { + ensembles = inventory.getEnsembles(parameters); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + if (ensembles != null && ensembles.size() > 1) { + Collections.sort(ensembles); + List pairs = new ArrayList(); + for (String ensemble : ensembles) { + ResourcePair pair = new ResourcePair(); + resourceData = getResourceData(); + HashMap newParameters = new HashMap( + parameters); + newParameters.put(GridConstants.ENSEMBLE_ID, + new RequestConstraint(ensemble)); + resourceData.setMetadataMap(newParameters); + pair.setResourceData(resourceData); + pair.setLoadProperties(loadProperties); + pair.setProperties(new ResourceProperties()); + pairs.add(pair); + } + constructResource(pairs); + } else { + resourceData = getResourceData(); + resourceData.setMetadataMap(parameters); + constructResource(); + } + } + @Override protected String[] queryData(String param, HashMap queryList) { diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridUpdater.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridUpdater.java index 227c654343..367873f2e3 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridUpdater.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridUpdater.java @@ -298,7 +298,7 @@ public class GridUpdater implements IAlertObserver { } } myUpdates.addAll(datauris); - ProductAlertObserver.processDerivedAlerts(datauris); + ProductAlertObserver.processDataURIAlerts(datauris); } /** diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java index 81c04a55b4..8dc2089ab6 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/RadarUpdater.java @@ -203,7 +203,7 @@ public class RadarUpdater implements IAlertObserver { "Unable to generate updates for derived product", e); } } - ProductAlertObserver.processDerivedAlerts(datauris); + ProductAlertObserver.processDataURIAlerts(datauris); } private CacheKey getCacheKey(RadarRequestableLevelNode rNode) { diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java index ed9a9b0ae8..0b9037e1f6 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java @@ -51,6 +51,7 @@ import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.ColorMapLoader; import com.raytheon.uf.viz.core.drawables.ColorMapParameters; +import com.raytheon.uf.viz.core.drawables.ColorMapParameters.PersistedParameters; import com.raytheon.uf.viz.core.drawables.IRenderable; import com.raytheon.uf.viz.core.drawables.PaintProperties; import com.raytheon.uf.viz.core.exception.VizException; @@ -595,6 +596,13 @@ public abstract class AbstractGridResource // reuse the old parameters. This is useful when the resource is // sharing capabilities, for example in an FFGVizGroupResource. newParameters = oldParameters; + } else if (oldParameters != null) { + newParameters.setColorMapName(oldParameters.getColorMapName()); + newParameters.setColorMap(oldParameters.getColorMap()); + PersistedParameters persisted = oldParameters.getPersisted(); + if (persisted != null) { + newParameters.applyPersistedParameters(persisted); + } } return newParameters; } diff --git a/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResourceData.java b/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResourceData.java index 71705c8b2d..10340b221c 100644 --- a/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResourceData.java +++ b/cave/com.raytheon.viz.lightning/src/com/raytheon/viz/lightning/LightningResourceData.java @@ -81,6 +81,16 @@ public class LightningResourceData extends AbstractRequestableResourceData { return rsc; } + @Override + public boolean isUpdatingOnMetadataOnly() { + return true; + } + + @Override + public boolean isRetrieveData() { + return true; + } + /** * @return the handlingPositiveStrikes */ diff --git a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResource.java b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResource.java index 06c0dcd3aa..58a3d61d28 100644 --- a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResource.java +++ b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResource.java @@ -157,7 +157,11 @@ public class MetarPrecipResource extends @Override protected void paintInternal(IGraphicsTarget target, PaintProperties paintProps) throws VizException { - List precips = data.get(paintProps.getDataTime()); + DataTime time = paintProps.getDataTime(); + if (time == null) { + return; + } + List precips = getPrecipData(time); if (precips == null) { dataProcessJob.schedule(); return; @@ -201,6 +205,19 @@ public class MetarPrecipResource extends target.drawStrings(strings); } + private List getPrecipData(DataTime time) { + List currData = null; + synchronized (data) { + currData = data.get(time); + } + if (currData != null) { + synchronized (currData) { + return new ArrayList(currData); + } + } + return null; + } + @Override protected void initInternal(IGraphicsTarget target) throws VizException { @@ -262,7 +279,7 @@ public class MetarPrecipResource extends Double magnification = getCapability(MagnificationCapability.class) .getMagnification(); - List precips = data.get(descriptor + List precips = getPrecipData(descriptor .getTimeForResource(this)); if (precips == null || precips.isEmpty()) { @@ -299,12 +316,14 @@ public class MetarPrecipResource extends private void processReproject() { if (reproject) { reproject = false; - for (List dataList : data.values()) { - for (RenderablePrecipData precip : dataList) { - Coordinate latLon = precip.getLatLon(); - double[] px = descriptor.worldToPixel(new double[] { - latLon.x, latLon.y }); - precip.string.setCoordinates(px[0], px[1], px[2]); + synchronized (data) { + for (List dataList : data.values()) { + for (RenderablePrecipData precip : dataList) { + Coordinate latLon = precip.getLatLon(); + double[] px = descriptor.worldToPixel(new double[] { + latLon.x, latLon.y }); + precip.string.setCoordinates(px[0], px[1], px[2]); + } } } } @@ -312,10 +331,12 @@ public class MetarPrecipResource extends } private void processRemoves() { - while (!removes.isEmpty()) { - DataTime toRemove = removes.poll(); - this.dataTimes.remove(toRemove); - this.data.remove(toRemove); + synchronized (data) { + while (!removes.isEmpty()) { + DataTime toRemove = removes.poll(); + this.dataTimes.remove(toRemove); + this.data.remove(toRemove); + } } } @@ -354,10 +375,13 @@ public class MetarPrecipResource extends // No need to reprocess times after the earliest update. continue; } - Iterator iter = entry.getValue().iterator(); - while (iter.hasNext()) { - if (newStations.contains(iter.next().getStationName())) { - iter.remove(); + synchronized (entry.getValue()) { + Iterator iter = entry.getValue() + .iterator(); + while (iter.hasNext()) { + if (newStations.contains(iter.next().getStationName())) { + iter.remove(); + } } } addData(time, container.getBasePrecipData(time)); @@ -393,6 +417,9 @@ public class MetarPrecipResource extends } int curIndex = frameInfo.getFrameIndex(); int count = frameInfo.getFrameCount(); + if (times.length != count) { + System.out.println("Uh oh"); + } // This will generate the number series 0, -1, 1, -2, 2, -3, 3... for (int i = 0; i < count / 2 + 1; i = i < 0 ? -i : -i - 1) { int index = (count + curIndex + i) % count; @@ -417,27 +444,31 @@ public class MetarPrecipResource extends } } } - // This will only happen if frames were removed while we were processing - // DOn't leave any half created frames - for (DataTime time : baseOnly) { - this.dataTimes.remove(time); - this.data.remove(time); + + synchronized (data) { + // This will only happen if frames were removed while we were + // processing. Don't leave any half created frames + for (DataTime time : baseOnly) { + this.dataTimes.remove(time); + this.data.remove(time); + } } } private void addData(DataTime time, List precips) { if (precips.isEmpty()) { if (!dataTimes.contains(time)) { - List newPrecips = Collections.emptyList(); - data.put(time, newPrecips); + synchronized (data) { + List newPrecips = Collections + .emptyList(); + data.put(time, newPrecips); + } dataTimes.add(time); } } if (data.containsKey(time)) { precips = new ArrayList(precips); - for (RenderablePrecipData pData : data.get(time)) { - precips.add(pData); - } + precips.addAll(getPrecipData(time)); } Collections.sort(precips, new Comparator() { @@ -480,9 +511,11 @@ public class MetarPrecipResource extends data.distValue = bestDist; newPrecips.add(data); } - data.put(time, newPrecips); - if (!dataTimes.contains(time)) { - dataTimes.add(time); + synchronized (data) { + data.put(time, newPrecips); + if (!dataTimes.contains(time)) { + dataTimes.add(time); + } } issueRefresh(); } diff --git a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResourceData.java b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResourceData.java index 2e0f5e823a..f6c2be7742 100644 --- a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResourceData.java +++ b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/MetarPrecipResourceData.java @@ -67,6 +67,16 @@ public class MetarPrecipResourceData extends AbstractRequestableResourceData { this.duration = duration; } + @Override + public boolean isUpdatingOnMetadataOnly() { + return true; + } + + @Override + public boolean isRetrieveData() { + return false; + } + @Override public int hashCode() { final int prime = 31; diff --git a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/util/PointMetadataContainer.java b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/util/PointMetadataContainer.java index 35e06b2f6f..5e48511836 100644 --- a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/util/PointMetadataContainer.java +++ b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/util/PointMetadataContainer.java @@ -102,15 +102,17 @@ public class PointMetadataContainer extends MetadataContainer { } pdc = pdca.getBaseRecords(baseParams, originalConstraints); for (PointDataLevelNode node : nodes) { - IDataRecord rec = pdc.getParameterRecord(node.getParameter()); Set cacheSet = new HashSet(); - cacheSet.add(new PointRequestableData(rec, pdc.getDescription( - node.getParameter()).getUnitObject())); - dataCache.put(node, cacheSet); - if (!Arrays.asList("id", "latitude", "longitude", "dataURI") - .contains(rec.getName())) { - pdc.remove(rec.getName()); + if (pdc != null) { + IDataRecord rec = pdc.getParameterRecord(node.getParameter()); + cacheSet.add(new PointRequestableData(rec, pdc.getDescription( + node.getParameter()).getUnitObject())); + if (!Arrays.asList("id", "latitude", "longitude", "dataURI") + .contains(rec.getName())) { + pdc.remove(rec.getName()); + } } + dataCache.put(node, cacheSet); } } diff --git a/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractCAVEComponent.java b/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractCAVEComponent.java index e9b60f47b8..72495a05bd 100644 --- a/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractCAVEComponent.java +++ b/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractCAVEComponent.java @@ -54,6 +54,7 @@ import com.raytheon.uf.viz.alertviz.SystemStatusHandler; import com.raytheon.uf.viz.alertviz.ui.dialogs.AlertVisualization; import com.raytheon.uf.viz.application.ProgramArguments; import com.raytheon.uf.viz.application.component.IStandaloneComponent; +import com.raytheon.uf.viz.core.RecordFactory; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.localization.CAVELocalizationNotificationObserver; import com.raytheon.uf.viz.core.localization.LocalizationConstants; @@ -383,9 +384,15 @@ public abstract class AbstractCAVEComponent implements IStandaloneComponent { protected void initializeObservers() { // Setup cave notification observer CAVELocalizationNotificationObserver.register(); - // Register product observers - ProductAlertObserver.addObserver(null, new MenuUpdater()); - ProductAlertObserver.addObserver(null, new AutoUpdater()); + registerProductAlerts(); } + protected void registerProductAlerts() { + // Register product observers + ProductAlertObserver.addObserver(null, new MenuUpdater()); + for (String plugin : RecordFactory.getInstance().getSupportedPlugins()) { + // Create separate AutoUpdater per plugin + ProductAlertObserver.addObserver(plugin, new AutoUpdater()); + } + } } diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleLoader.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleLoader.java new file mode 100644 index 0000000000..c9056f8739 --- /dev/null +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleLoader.java @@ -0,0 +1,346 @@ +package com.raytheon.viz.ui; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.IEditorPart; + +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.viz.core.AbstractTimeMatcher; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.globals.VizGlobalsManager; +import com.raytheon.uf.viz.core.procedures.Bundle; +import com.raytheon.viz.ui.editor.IMultiPaneEditor; + +/** + * + * Loads a bundle to a container. Replaces contents of bundle on the container + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 8, 2013            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +public class BundleLoader extends Job { + + protected static final IUFStatusHandler statusHandler = UFStatus + .getHandler(BundleLoader.class); + + public static enum BundleInfoType { + FILE_LOCATION, XML + } + + protected static class LoadItem { + + public final IDisplayPane loadTo; + + public final IRenderableDisplay loadFrom; + + public LoadItem(IDisplayPane loadTo, IRenderableDisplay loadFrom) { + this.loadTo = loadTo; + this.loadFrom = loadFrom; + } + + } + + private class InstantiationTask implements Runnable { + + private LoadItem loadItem; + + private InstantiationTask(LoadItem loadItem) { + this.loadItem = loadItem; + } + + @Override + public void run() { + IDisplayPane loadTo = loadItem.loadTo; + IRenderableDisplay loadFrom = loadItem.loadFrom; + if (loadTo.getDescriptor() != loadFrom.getDescriptor()) { + load(loadTo, loadFrom); + } + loadTo.getDescriptor().getResourceList() + .instantiateResources(loadTo.getDescriptor(), true); + } + + } + + protected IDisplayPaneContainer container; + + private Bundle bundle; + + public BundleLoader(IDisplayPaneContainer container, Bundle bundle) { + this("Bundle Loader", container, bundle); + } + + protected BundleLoader(String name, IDisplayPaneContainer container, + Bundle bundle) { + super(name); + this.container = container; + this.bundle = bundle; + } + + /** + * Runs the loading synchronously. + */ + public final void run() { + run(new NullProgressMonitor()); + } + + @Override + protected final IStatus run(IProgressMonitor monitor) { + long t0 = System.currentTimeMillis(); + try { + loadBundleToContainer(container, bundle); + if (bundle.getLoopProperties() != null) { + container.setLoopProperties(bundle.getLoopProperties()); + } + + /** refresh the editor */ + container.refresh(); + + if (container instanceof IEditorPart) { + /** update the history list */ + HistoryList.getInstance().refreshLatestBundle( + HistoryList.prepareHistoryEntry(container)); + } + + if (container instanceof IEditorPart) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + VizGlobalsManager.getCurrentInstance().updateUI( + container); + } + }); + } + } catch (VizException e) { + return new Status(IStatus.ERROR, UiPlugin.PLUGIN_ID, + "Error loading bundle", e); + } + long t2 = System.currentTimeMillis(); + System.out.println("Total bundle retrieval: " + (t2 - t0)); + return Status.OK_STATUS; + } + + /** + * Loads a {@link Bundle} onto an {@link IDisplayPaneContainer} + * + * @param container + * @param bundle + * @throws VizException + */ + private final void loadBundleToContainer(IDisplayPaneContainer container, + Bundle bundle) throws VizException { + LoadItem[] items = getLoadItems(container, bundle); + int numItems = items.length; + + if (numItems > 0) { + Thread[] threads = new Thread[numItems - 1]; + for (int i = 0; i < numItems; ++i) { + Thread t = new Thread(new InstantiationTask(items[i])); + if (i == 0) { + IRenderableDisplay loadFrom = items[i].loadFrom; + IDisplayPane loadTo = items[i].loadTo; + AbstractTimeMatcher srcTimeMatcher = loadFrom + .getDescriptor().getTimeMatcher(); + if (srcTimeMatcher != null) { + loadTo.getDescriptor().getTimeMatcher() + .copyFrom(srcTimeMatcher); + } + loadTo.getDescriptor().getTimeMatcher().resetMultiload(); + t.run(); + } else { + t.start(); + threads[i - 1] = t; + } + } + + for (Thread t : threads) { + try { + t.join(); + } catch (InterruptedException e) { + // Ignore + } + } + } + } + + /** + * Gets the pairing of display->pane loading that should occur. Each item + * will have {@link #load(IDisplayPane, IRenderableDisplay)} called on it + * + * @param container + * @param bundle + * @return + * @throws VizException + */ + protected LoadItem[] getLoadItems(IDisplayPaneContainer container, + Bundle bundle) throws VizException { + IDisplayPane[] containerPanes = container.getDisplayPanes(); + AbstractRenderableDisplay[] bundleDisplays = bundle.getDisplays(); + + if (containerPanes.length != bundleDisplays.length) { + boolean success = ensureOneToOne(container, bundle); + containerPanes = container.getDisplayPanes(); + if (success == false) { + throw new VizException("Unable to load " + + bundleDisplays.length + + " displays onto container with " + + containerPanes.length + " panes"); + } + } + + int numPanes = containerPanes.length; + LoadItem[] items = new LoadItem[numPanes]; + + List orderedDisplays = Arrays + .asList(bundleDisplays); + for (int i = 0; i < numPanes; ++i) { + IDescriptor desc = bundleDisplays[i].getDescriptor(); + if (desc.getTimeMatcher() != null) { + orderedDisplays = desc.getTimeMatcher().getDisplayLoadOrder( + orderedDisplays); + for (AbstractRenderableDisplay d : orderedDisplays) { + d.getDescriptor().synchronizeTimeMatching(desc); + } + break; + } + } + if (orderedDisplays.size() != numPanes) { + throw new VizException( + "Error ordering bundle displays. Number of displays returned not same as passed in"); + } + + int j = 0; + for (AbstractRenderableDisplay display : orderedDisplays) { + for (int i = 0; i < numPanes; ++i) { + if (display == bundleDisplays[i]) { + items[j] = new LoadItem(containerPanes[i], + bundleDisplays[i]); + } + } + ++j; + } + + return items; + } + + /** + * Ensures there is a one to one relationship for number of panes on + * container to number of displays in bundle + * + * @param container + * @param bundle + * @return true of mapping is 1-1, false otherwise + */ + protected boolean ensureOneToOne(IDisplayPaneContainer container, + Bundle bundle) { + IDisplayPane[] containerPanes = container.getDisplayPanes(); + AbstractRenderableDisplay[] bundleDisplays = bundle.getDisplays(); + + // Attempt to match 1-1 pane to display + if (container instanceof IMultiPaneEditor) { + final IMultiPaneEditor mpe = (IMultiPaneEditor) container; + final int numPanes = containerPanes.length; + final int numDisplays = bundleDisplays.length; + final IDisplayPane[] cPanes = containerPanes; + final AbstractRenderableDisplay[] bDisplays = bundleDisplays; + VizApp.runSync(new Runnable() { + @Override + public void run() { + for (int i = numPanes; i < numDisplays; ++i) { + // This will hit if fewer panes than displays + mpe.addPane(bDisplays[i]); + } + for (int i = numDisplays; i < numPanes; ++i) { + // This will hit if fewer displays than panes + mpe.removePane(cPanes[i]); + } + } + }); + } + containerPanes = container.getDisplayPanes(); + return containerPanes.length == bundleDisplays.length; + } + + /** + * Loads the renderable display onto the pane + * + * @param loadTo + * @param loadFrom + */ + protected void load(final IDisplayPane loadTo, + final IRenderableDisplay loadFrom) { + VizApp.runSync(new Runnable() { + @Override + public void run() { + loadTo.setRenderableDisplay(loadFrom); + } + }); + } + + /** + * Gets a bundle object from bundle text, text type is specified by + * {@link BundleInfoType} passed in + * + * @param bundleText + * @param variables + * @param type + * @return + * @throws VizException + */ + public static Bundle getBundle(String bundleText, + Map variables, BundleInfoType type) + throws VizException { + /** Make sure bundle text is not null */ + if (bundleText == null) { + throw new IllegalArgumentException("Bundle text cannot be null"); + } + + Bundle b = null; + /** Is the bundle location the bundle xml or a file with the xml? */ + if (type == BundleInfoType.FILE_LOCATION) { + /** File with xml */ + b = Bundle.unmarshalBundle(PathManagerFactory.getPathManager() + .getStaticFile(bundleText), variables); + } else { + /** bundleLocation variable contains the xml */ + b = Bundle.unmarshalBundle(bundleText, variables); + } + + return b; + } + + /** + * Schedules a {@link BundleLoader} to run to load the bundle on the + * container + * + * @param container + * @param b + */ + public static void loadTo(IDisplayPaneContainer container, Bundle b) { + new BundleLoader(container, b).schedule(); + } +} diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleProductLoader.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleProductLoader.java new file mode 100644 index 0000000000..f24c57d517 --- /dev/null +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleProductLoader.java @@ -0,0 +1,168 @@ +package com.raytheon.viz.ui; + +import java.util.ArrayList; +import java.util.List; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.procedures.Bundle; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.viz.core.ColorUtil; +import com.raytheon.viz.ui.editor.IMultiPaneEditor; + +/** + * + * Loads a bundle as a product to a container. This will add the resources from + * the bundle displays onto the container instead of replacing + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 8, 2013            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +public class BundleProductLoader extends BundleLoader { + + public BundleProductLoader(IDisplayPaneContainer container, Bundle bundle) { + super("Product Loader", container, bundle); + } + + @Override + protected LoadItem[] getLoadItems(IDisplayPaneContainer container, + Bundle bundle) throws VizException { + IDisplayPane[] containerPanes = container.getDisplayPanes(); + AbstractRenderableDisplay[] bundleDisplays = bundle.getDisplays(); + + int bundleSize = bundleDisplays.length; + int editorSize = containerPanes.length; + + IDisplayPane[] loadTo; + IRenderableDisplay[] loadFrom; + + IDisplayPane selected = null; + if (container instanceof IMultiPaneEditor) { + selected = ((IMultiPaneEditor) container) + .getSelectedPane(IMultiPaneEditor.LOAD_ACTION); + } + + // Figure out what panes to load to + if (selected != null && bundleSize == 1) { + // Only load to selected pane + loadTo = new IDisplayPane[] { selected }; + loadFrom = new IRenderableDisplay[] { bundleDisplays[0] }; + } else if (bundleSize == 1 && editorSize >= 1) { + loadTo = new IDisplayPane[editorSize]; + loadFrom = new IRenderableDisplay[editorSize]; + for (int i = 0; i < editorSize; ++i) { + loadTo[i] = containerPanes[i]; + loadFrom[i] = bundleDisplays[0].cloneDisplay(); + } + } else { + // Load 1-1 + if (editorSize < bundleSize) { + // If fewer container panes than bundle displays, attempt to + // ensure 1-1 by adding panes + ensureOneToOne(container, bundle); + containerPanes = container.getDisplayPanes(); + editorSize = containerPanes.length; + } + // Load what is possible + int maxCanLoad = Math.min(editorSize, bundleSize); + loadTo = new IDisplayPane[maxCanLoad]; + loadFrom = new IRenderableDisplay[maxCanLoad]; + for (int i = 0; i < maxCanLoad; ++i) { + loadTo[i] = containerPanes[i]; + loadFrom[i] = bundleDisplays[i]; + } + } + + LoadItem[] items = new LoadItem[loadTo.length]; + for (int i = 0; i < items.length; ++i) { + items[i] = new LoadItem(loadTo[i], loadFrom[i]); + } + return items; + } + + @Override + protected void load(IDisplayPane loadTo, IRenderableDisplay loadFrom) { + IDescriptor existingDescriptor = loadTo.getDescriptor(); + IDescriptor fromDescriptor = loadFrom.getDescriptor(); + + /** + * Update the frame count based on what has been listed in the bundle if + * we don't have times already loaded + */ + FramesInfo info = existingDescriptor.getFramesInfo(); + if (info.getFrameCount() == 0) { + existingDescriptor.setNumberOfFrames(fromDescriptor + .getNumberOfFrames()); + } + + // Pull out the resources to load + ResourceList rscs = loadFrom.getDescriptor().getResourceList(); + List resourcesToLoad = new ArrayList(); + + for (ResourcePair rp : rscs) { + if (rp.getProperties().isSystemResource() == false) { + resourcesToLoad.add(rp); + } + } + + rscs.clear(); + + /** + * For each resource pair in the bundle resources: Give a unique color + * for the legend if one isn't set, add to pane's descriptor's resource + * list + */ + for (ResourcePair rp : resourcesToLoad) { + AbstractResourceData ard = rp.getResourceData(); + + try { + ard.configure(rp.getLoadProperties(), existingDescriptor); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + + boolean newRP = true; + if (existingDescriptor.getResourceList().contains(rp)) { + newRP = false; + } + if (newRP + && (rp.getProperties().isSystemResource() == false && !rp + .getLoadProperties().getCapabilities() + .hasCapability(ColorableCapability.class))) { + rp.getLoadProperties() + .getCapabilities() + .getCapability(rp.getResourceData(), + ColorableCapability.class) + .setColor( + ColorUtil.getNewColor( + container.getDisplayPanes(), + existingDescriptor, rp)); + } + + if (newRP) { + existingDescriptor.getResourceList().add(rp); + } + } + } + +} diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/HistoryList.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/HistoryList.java index 751b7ac625..e399a3d114 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/HistoryList.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/HistoryList.java @@ -256,7 +256,10 @@ public class HistoryList { } public static Bundle prepareHistoryEntry() { - IDisplayPaneContainer cont = EditorUtil.getActiveVizContainer(); + return prepareHistoryEntry(EditorUtil.getActiveVizContainer()); + } + + public static Bundle prepareHistoryEntry(IDisplayPaneContainer cont) { if (cont != null) { Bundle b = new Bundle(); com.raytheon.uf.viz.core.IDisplayPane[] panes = cont diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/MenuLoader.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/MenuLoader.java deleted file mode 100644 index 4c6f180cd4..0000000000 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/MenuLoader.java +++ /dev/null @@ -1,350 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.viz.ui; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; - -import com.raytheon.uf.common.localization.PathManagerFactory; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.viz.core.AbstractTimeMatcher; -import com.raytheon.uf.viz.core.IDisplayPane; -import com.raytheon.uf.viz.core.VizApp; -import com.raytheon.uf.viz.core.drawables.IDescriptor; -import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; -import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; -import com.raytheon.uf.viz.core.drawables.ResourcePair; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.globals.VizGlobalsManager; -import com.raytheon.uf.viz.core.procedures.Bundle; -import com.raytheon.uf.viz.core.rsc.AbstractResourceData; -import com.raytheon.uf.viz.core.rsc.ResourceList; -import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; -import com.raytheon.viz.core.ColorUtil; -import com.raytheon.viz.ui.editor.AbstractEditor; -import com.raytheon.viz.ui.editor.IMultiPaneEditor; - -/** - * TODO Add Description - * - *
- * 
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Apr 2, 2009            chammack     Initial creation
- * Apr 7, 2009      2215  jsanchez     Updated the scaleFile.
- * June 25, 2010    1691  bkowal       The frame count for the created / 
- *                                     discovered editor will now be
- *                                     updated to match the frame
- *                                     count that was specified in the bundle.
- * 
- * 
- * - * @author chammack - * @version 1.0 - */ - -public class MenuLoader extends Job { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(MenuLoader.class); - - private Bundle bundle; - - private AbstractEditor editor; - - private class InstantiationThread extends Thread { - private IDisplayPane loadTo; - - private IRenderableDisplay loadFrom; - - public InstantiationThread(IDisplayPane loadTo, - IRenderableDisplay loadFrom) { - this.loadTo = loadTo; - this.loadFrom = loadFrom; - } - - @Override - public void run() { - IDescriptor existingDescriptor = loadTo.getDescriptor(); - - /** - * Update the frame count based on what has been listed in the - * bundle if we don't have times already loaded - */ - FramesInfo info = existingDescriptor.getFramesInfo(); - if (info.getFrameCount() == 0) { - existingDescriptor.setNumberOfFrames(loadFrom.getDescriptor() - .getNumberOfFrames()); - } - - // Pull out the resources to load - ResourceList rscs = loadFrom.getDescriptor().getResourceList(); - List resourcesToLoad = new ArrayList(); - - for (ResourcePair rp : rscs) { - if (rp.getProperties().isSystemResource() == false) { - resourcesToLoad.add(rp); - } - } - - rscs.clear(); - - /** - * For each resource pair in the bundle resources: Give a unique - * color for the legend if one isn't set, add to pane's descriptor's - * resource list - */ - for (ResourcePair rp : resourcesToLoad) { - AbstractResourceData ard = rp.getResourceData(); - - try { - ard.configure(rp.getLoadProperties(), existingDescriptor); - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, - e.getLocalizedMessage(), e); - } - - boolean newRP = true; - if (existingDescriptor.getResourceList().contains(rp)) { - newRP = false; - } - if (newRP - && (rp.getProperties().isSystemResource() == false && !rp - .getLoadProperties().getCapabilities() - .hasCapability(ColorableCapability.class))) { - rp.getLoadProperties() - .getCapabilities() - .getCapability(rp.getResourceData(), - ColorableCapability.class) - .setColor( - ColorUtil.getNewColor( - editor.getDisplayPanes(), - existingDescriptor, rp)); - } - - if (newRP) { - existingDescriptor.getResourceList().add(rp); - } - } - - existingDescriptor.getResourceList().instantiateResources( - existingDescriptor, true); - } - } - - public static enum BundleInfoType { - FILE_LOCATION, XML - } - - public MenuLoader(Bundle b, AbstractEditor editor) { - super("Request EDEX Product"); - this.bundle = b; - this.editor = editor; - } - - public static void loadProduct(final String editorType, - final String bundleLocation, final Map variables) - throws VizException { - loadProduct(editorType, bundleLocation, variables, - BundleInfoType.FILE_LOCATION); - } - - public static void loadProduct(String editorType, String bundleLocation, - Map variables, BundleInfoType type) - throws VizException { - Bundle b = null; - - /** Make sure bundle location is not null */ - if (bundleLocation == null) { - throw new VizException("bundleLocation was null"); - } - - /** Is the bundle location the bundle xml or a file with the xml? */ - if (type.equals(BundleInfoType.FILE_LOCATION)) { - /** File with xml */ - b = Bundle.unmarshalBundle(PathManagerFactory.getPathManager() - .getStaticFile(bundleLocation), variables); - } else { - /** bundleLocation variable contains the xml */ - b = Bundle.unmarshalBundle(bundleLocation, null); - } - - /** Load the editor from the bundle */ - AbstractEditor editor = null; - editor = UiUtil.createOrOpenEditor(editorType, b.getDisplays()); - - /** Error loading the editor */ - if (editor == null) { - throw new VizException("unable to get editor: " + editorType); - } - - /** - * If the descriptor in the bundle did not get set as the descriptor in - * the editor, we need to go through and add the resources in the - * bundle's IDisplayPane's descriptor to the editor's IDisplayPane's - * descriptor, which is done in the job - */ - if (editor.getDisplayPanes()[0].getDescriptor() != b.getDisplays()[0] - .getDescriptor()) { - Job j = new MenuLoader(b, editor); - j.schedule(); - } else { - /** - * The editor and bundle have the same descriptors meaning the - * editor was opened from the bundle so we need to instantiate the - * resources on them only (this needs to be done outside the job bc - * paint will be called immediately after this and the resources may - * not have been instantiated yet. - * - * TODO: There may be a way to create a list of resources from the - * bundle and in this statement just remove the resources from the - * editor then re add them in the job. so this doesn't hang on - * construction of the resource - */ - for (IDisplayPane pane : editor.getDisplayPanes()) { - pane.getDescriptor().getResourceList() - .instantiateResources(pane.getDescriptor(), true); - } - HistoryList.getInstance().refreshLatestBundle(); - } - - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - long t0 = System.currentTimeMillis(); - try { - /** extracted to method when doing a refactor, not really needed */ - loadExisting(); - /** refresh the editor */ - editor.refresh(); - /** update the history list */ - HistoryList.getInstance().refreshLatestBundle(); - } catch (VizException e) { - return new Status(IStatus.ERROR, UiPlugin.PLUGIN_ID, - "Error loading bundle", e); - } - long t2 = System.currentTimeMillis(); - System.out.println("Total bundle retrieval: " + (t2 - t0)); - return Status.OK_STATUS; - } - - private void loadExisting() throws VizException { - IDisplayPane selected = null; - if (editor instanceof IMultiPaneEditor) { - selected = ((IMultiPaneEditor) editor) - .getSelectedPane(IMultiPaneEditor.LOAD_ACTION); - } - - int bundleSize = bundle.getDisplays().length; - int editorSize = editor.getDisplayPanes().length; - - List loadToPanes = new ArrayList(); - List loadFromBundle = new ArrayList(); - List executionThreads = new ArrayList(); - - // Figure out what panes to load to - if (selected != null && bundleSize == 1) { - loadToPanes.add(selected); - loadFromBundle.add(bundle.getDisplays()[0]); - } else if (selected == null && bundleSize == 1) { - // load to all panes the single bundle display - for (IDisplayPane pane : editor.getDisplayPanes()) { - loadToPanes.add(pane); - loadFromBundle.add(bundle.getDisplays()[0].cloneDisplay()); - } - } else { - int max = Math.max(bundleSize, editorSize); - for (int i = 0; i < max; ++i) { - if (editorSize > i) { - loadToPanes.add(editor.getDisplayPanes()[i]); - } else { - loadToPanes.add(null); - } - - if (bundleSize > i) { - loadFromBundle.add(bundle.getDisplays()[i]); - } else { - loadFromBundle.add(null); - } - } - } - - for (int i = 0; i < loadToPanes.size(); ++i) { - IDisplayPane loadTo = loadToPanes.get(i); - final IRenderableDisplay loadFrom = loadFromBundle.get(i); - if (i == 0) { - AbstractTimeMatcher srcTimeMatcher = loadFrom.getDescriptor() - .getTimeMatcher(); - if (srcTimeMatcher != null) { - loadTo.getDescriptor().getTimeMatcher() - .copyFrom(srcTimeMatcher); - } - loadTo.getDescriptor().getTimeMatcher().resetMultiload(); - new InstantiationThread(loadTo, loadFrom).run(); - continue; - } - - if (loadFrom == null) { - continue; - } else if (loadTo == null) { - if (editor instanceof IMultiPaneEditor) { - VizApp.runSync(new Runnable() { - @Override - public void run() { - ((IMultiPaneEditor) (editor)).addPane(loadFrom); - } - }); - - } - continue; - } - - Thread t = new InstantiationThread(loadTo, loadFrom); - t.start(); - executionThreads.add(t); - } - - for (Thread t : executionThreads) { - try { - t.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - VizApp.runAsync(new Runnable() { - @Override - public void run() { - VizGlobalsManager.getCurrentInstance().updateUI(editor); - } - }); - - } -} diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/LoadSerializedXml.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/LoadSerializedXml.java index 86ee7cfa47..33fa3207dc 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/LoadSerializedXml.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/LoadSerializedXml.java @@ -20,9 +20,6 @@ package com.raytheon.viz.ui.actions; import java.io.File; -import java.util.Arrays; -import java.util.List; -import java.util.Map; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -46,21 +43,16 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.DescriptorMap; -import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.IDisplayPaneContainer; -import com.raytheon.uf.viz.core.VizApp; -import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; import com.raytheon.uf.viz.core.drawables.IDescriptor; import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.globals.VizGlobalsManager; import com.raytheon.uf.viz.core.procedures.Bundle; import com.raytheon.uf.viz.core.procedures.Procedure; -import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.viz.ui.BundleLoader; import com.raytheon.viz.ui.UiUtil; import com.raytheon.viz.ui.VizWorkbenchManager; import com.raytheon.viz.ui.editor.AbstractEditor; -import com.raytheon.viz.ui.editor.IMultiPaneEditor; /** * Handles loading of bundles or procedures @@ -133,11 +125,10 @@ public class LoadSerializedXml extends AbstractHandler { IDescriptor bundleDescriptor = renderableDisplay.getDescriptor(); String bundleEditorId = DescriptorMap.getEditorId(bundleDescriptor .getClass().getName()); - synchronizeDisplays(bundle); AbstractEditor editor = UiUtil.createOrOpenEditor(bundleEditorId, bundle.getDisplays()); - loadTo(editor, bundle); + BundleLoader.loadTo(editor, bundle); } public static void loadProcedureToScreen(Procedure procedure, @@ -183,7 +174,6 @@ public class LoadSerializedXml extends AbstractHandler { for (Bundle b : bundles) { // If an editor is specified, or no view part is specified, // assume an editor part - synchronizeDisplays(b); if (b.getView() == null) { String editorName = b.getEditor(); AbstractEditor openedEditor = UiUtil.createEditor(editorName, @@ -202,33 +192,22 @@ public class LoadSerializedXml extends AbstractHandler { } } - loadTo(openedEditor, b); + BundleLoader.loadTo(openedEditor, b); } else { // There is a view part specified IViewPart part = UiUtil.findView(windowToLoadTo, b.getView(), false); if (part != null && part instanceof IDisplayPaneContainer) { - loadTo((IDisplayPaneContainer) part, b); + BundleLoader.loadTo((IDisplayPaneContainer) part, b); } } } } - private static void synchronizeDisplays(Bundle b) { - IDescriptor firstDesc = null; - for (AbstractRenderableDisplay d : b.getDisplays()) { - if (firstDesc == null) { - firstDesc = d.getDescriptor(); - } else { - d.getDescriptor().synchronizeTimeMatching(firstDesc); - } - } - } - /** - * Load a bundle to a container + * Use {@link BundleLoader} instead * * @param editor * the container to load to @@ -236,119 +215,10 @@ public class LoadSerializedXml extends AbstractHandler { * the bundle * @throws VizException */ - public static void loadTo(final IDisplayPaneContainer container, - final Bundle b) throws VizException { - final int containerSize = container.getDisplayPanes().length; - final boolean multiEditor = container instanceof IMultiPaneEditor; - - if (multiEditor) { - if (container.getDisplayPanes().length > b.getDisplays().length) { - VizApp.runSync(new Runnable() { - @Override - public void run() { - while (container.getDisplayPanes().length > b - .getDisplays().length) { - ((IMultiPaneEditor) container).removePane(container - .getDisplayPanes()[container - .getDisplayPanes().length - 1]); - } - } - }); - } - - } - List orderedDisplays = Arrays.asList(b - .getDisplays()); - IDescriptor firstDesc = orderedDisplays.get(0).getDescriptor(); - if (firstDesc != null && firstDesc.getTimeMatcher() != null) { - orderedDisplays = firstDesc.getTimeMatcher().getDisplayLoadOrder( - orderedDisplays); - } - for (AbstractRenderableDisplay d : orderedDisplays) { - d.getDescriptor().synchronizeTimeMatching(firstDesc); - ResourceList rl = d.getDescriptor().getResourceList(); - rl.instantiateResources(d.getDescriptor(), true); - } - - final VizException[] errors = new VizException[1]; - - VizApp.runSync(new Runnable() { - @Override - public void run() { - int i = 0; - for (AbstractRenderableDisplay d : b.getDisplays()) { - if (i >= containerSize && multiEditor) { - ((IMultiPaneEditor) container).addPane(d); - } else if (i >= containerSize) { - errors[0] = new VizException( - "Unable to add panes to non IMultiPaneEditor"); - return; - } else { - IRenderableDisplay oldDisplay = container - .getDisplayPanes()[i].getRenderableDisplay(); - if (oldDisplay != null && oldDisplay != d) { - oldDisplay.dispose(); - } - container.getDisplayPanes()[i].setRenderableDisplay(d); - container.getDisplayPanes()[i].resize(); - container.getDisplayPanes()[i].refresh(); - } - i++; - } - - if (b.getLoopProperties() != null) { - container.setLoopProperties(b.getLoopProperties()); - } - - // if loading to an editor, update the globals - if (container instanceof IEditorPart) { - VizGlobalsManager.getCurrentInstance().updateUI(container); - } - } - }); - - if (errors[0] != null) { - throw errors[0]; - } - } - - /** - * Load a bundle from a file into a container - * - * @param editor - * the container to load to - * @param f - * the file containing the bundle - * @param descriptor - * Optional: A descriptor that should be used for time matching - * @throws VizException - */ - public static void loadTo(File f, Map variables) + @Deprecated + public static void loadTo(final IDisplayPaneContainer container, Bundle b) throws VizException { - Bundle b = Bundle.unmarshalBundle(f, variables); - - IRenderableDisplay renderableDisplay = b.getDisplays()[0]; - IDescriptor bundleDescriptor = renderableDisplay.getDescriptor(); - String bundleEditorId = DescriptorMap.getEditorId(bundleDescriptor - .getClass().getName()); - AbstractEditor editor = UiUtil.createOrOpenEditor(bundleEditorId, - b.getDisplays()); - - loadTo(editor, b); + new BundleLoader(container, b).run(); } - public static void loadTo(IDisplayPane pane, File f, - Map variables) throws VizException { - - Bundle b = Bundle.unmarshalBundle(f, variables); - - for (AbstractRenderableDisplay d : b.getDisplays()) { - ResourceList rl = d.getDescriptor().getResourceList(); - rl.instantiateResources(d.getDescriptor(), true); - - pane.setRenderableDisplay(d); - pane.resize(); - pane.refresh(); - } - } } diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/perspectives/AbstractVizPerspectiveManager.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/perspectives/AbstractVizPerspectiveManager.java index 5636abbd62..779fd25940 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/perspectives/AbstractVizPerspectiveManager.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/perspectives/AbstractVizPerspectiveManager.java @@ -136,6 +136,20 @@ public abstract class AbstractVizPerspectiveManager implements @Override public void partDeactivated(IWorkbenchPart part) { + // update editor on last selected modal tool + if (part instanceof IEditorPart + && part instanceof IDisplayPaneContainer) { + AbstractVizPerspectiveManager mgr = VizPerspectiveListener + .getCurrentPerspectiveManager(); + if (mgr != null) { + for (AbstractModalTool tool : mgr.getToolManager() + .getSelectedModalTools()) { + if (tool.getCurrentEditor() == part) { + tool.deactivate(); + } + } + } + } } @Override @@ -362,12 +376,6 @@ public abstract class AbstractVizPerspectiveManager implements page.hideEditor(ref); } - for (AbstractModalTool tool : toolManager.getSelectedModalTools()) { - if (tool != null) { - tool.deactivate(); - } - } - deactivateDialogs(); deactivateContexts(); removeFromStatusLine(); diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/tools/AbstractModalTool.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/tools/AbstractModalTool.java index 450b1860df..64da65bfb4 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/tools/AbstractModalTool.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/tools/AbstractModalTool.java @@ -156,6 +156,7 @@ public abstract class AbstractModalTool extends AbstractTool { this.setEnabled(false); if (editor != null) { deactivateTool(); + editor = null; } } diff --git a/cave/com.raytheon.viz.volumebrowser/src/com/raytheon/viz/volumebrowser/vbui/ProductTableComp.java b/cave/com.raytheon.viz.volumebrowser/src/com/raytheon/viz/volumebrowser/vbui/ProductTableComp.java index acc2eaff5f..11ff433ab4 100644 --- a/cave/com.raytheon.viz.volumebrowser/src/com/raytheon/viz/volumebrowser/vbui/ProductTableComp.java +++ b/cave/com.raytheon.viz.volumebrowser/src/com/raytheon/viz/volumebrowser/vbui/ProductTableComp.java @@ -88,7 +88,7 @@ import com.raytheon.viz.core.slice.request.VerticalPointRequest.TimeDirection; import com.raytheon.viz.skewt.SkewtDisplay; import com.raytheon.viz.skewt.rscdata.SkewTResourceData; import com.raytheon.viz.ui.EditorUtil; -import com.raytheon.viz.ui.MenuLoader; +import com.raytheon.viz.ui.BundleProductLoader; import com.raytheon.viz.ui.UiUtil; import com.raytheon.viz.ui.editor.AbstractEditor; import com.raytheon.viz.ui.editor.IMultiPaneEditor; @@ -1078,7 +1078,7 @@ public class ProductTableComp extends Composite { Bundle b = new Bundle(); b.setDisplays(new AbstractRenderableDisplay[] { display }); - Job j = new MenuLoader(b, editor); + Job j = new BundleProductLoader(editor, b); j.schedule(); } } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java index e44dbcf3a5..9ef6bc3676 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java @@ -15,6 +15,7 @@ import org.geotools.referencing.GeodeticCalculator; import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration; import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration; +import com.raytheon.uf.common.dataplugin.warning.gis.PreparedGeometryCollection; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.geospatial.SpatialQueryResult; import com.raytheon.uf.viz.core.exception.VizException; @@ -26,7 +27,6 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.prep.PreparedGeometry; -import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; /** * @@ -146,7 +146,7 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor { boolean userDirections = Boolean.valueOf(String.valueOf(attributes .get(useDirectionField))); if (userDirections) { - PreparedGeometry prepGeom = PreparedGeometryFactory.prepare(geom); + PreparedGeometry prepGeom = new PreparedGeometryCollection(geom); if (prepGeom.intersects(searchArea) && !prepGeom.within(searchArea)) { Geometry intersection = searchArea.intersection(geom); partOfArea = GisUtil.asStringList(calculateLocationPortion( diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java index ea42c71a28..018126daa8 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java @@ -50,6 +50,7 @@ import com.raytheon.viz.warngen.gui.WarngenLayer; import com.raytheon.viz.warngen.suppress.SuppressMap; import com.raytheon.viz.warngen.util.Abbreviation; import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.prep.PreparedGeometry; /** * Area @@ -176,6 +177,7 @@ public class Area { GeodeticCalculator gc = new GeodeticCalculator(); for (GeospatialData regionFeature : countyMap.values()) { Geometry regionGeom = regionFeature.geometry; + PreparedGeometry preparedRegionGeom = regionFeature.prepGeom; AffectedAreas area = new AffectedAreas(); area.name = regionFeature.attributes.get(areaField).toString(); area.fips = regionFeature.attributes.get(fipsField).toString(); @@ -237,7 +239,7 @@ public class Area { if (ptFeatures != null) { List pointList = new ArrayList(); for (SpatialQueryResult ptRslt : ptFeatures) { - if (regionGeom.contains(ptRslt.geometry)) { + if (preparedRegionGeom.contains(ptRslt.geometry)) { pointList.add(String.valueOf(ptRslt.attributes .get(pointField))); } @@ -331,7 +333,7 @@ public class Area { } return retVal; } - + public static List converFeAreaToPartList(String feArea) { final List partList = new ArrayList(); if (feArea == null) { diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java index 538a6294a7..f677f85ae4 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java @@ -29,6 +29,7 @@ import java.util.List; import org.geotools.referencing.GeodeticCalculator; +import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil; import com.raytheon.viz.warngen.suppress.SuppressMap; import com.vividsolutions.jts.algorithm.CGAlgorithms; import com.vividsolutions.jts.geom.Coordinate; @@ -37,7 +38,6 @@ import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; -import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; /** @@ -206,27 +206,21 @@ public class GisUtil { yDirection = Direction.SOUTH; } + List geoms = new ArrayList(geom.getNumGeometries()); + GeometryUtil.buildGeometryList(geoms, geom); boolean isExtreme = false; - Coordinate[] coords; - if (geom instanceof Polygon) { - LineString lineString = ((Polygon) geom).getExteriorRing(); - coords = lineString.getCoordinates(); - isExtreme = isExtreme(coords, point, - (extremaThresholdX + extremaThresholdY) / 2.0); - } else if (geom instanceof MultiPolygon) { - int geoms = ((MultiPolygon) geom).getNumGeometries(); - for (int i = 0; i < geoms; i++) { - LineString lineString = ((Polygon) ((MultiPolygon) geom) - .getGeometryN(i)).getExteriorRing(); - coords = lineString.getCoordinates(); - if (isExtreme(coords, point, + for (Geometry g : geoms) { + if (g instanceof Polygon) { + LineString lineString = ((Polygon) g).getExteriorRing(); + if (isExtreme(lineString.getCoordinates(), point, (extremaThresholdX + extremaThresholdY) / 2.0)) { isExtreme = true; break; } } } + EnumSet retVal = EnumSet.noneOf(Direction.class); if (xDirection != null && !suppressType.equals(SuppressMap.EAST_WEST) diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PolygonUtil.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PolygonUtil.java index 1d65601dd9..cf583d39d3 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PolygonUtil.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PolygonUtil.java @@ -30,6 +30,7 @@ import org.geotools.referencing.operation.DefaultMathTransformFactory; import org.opengis.metadata.spatial.PixelOrientation; import org.opengis.referencing.operation.MathTransform; +import com.raytheon.uf.common.dataplugin.warning.gis.PreparedGeometryCollection; import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil; import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.exception.VizException; @@ -44,7 +45,6 @@ import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineSegment; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.prep.PreparedGeometry; -import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; /** * Utility for polygon operations @@ -57,7 +57,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; * ------------ ---------- ----------- -------------------------- * Dec 1, 2010 mschenke Initial creation * 12/06/2012 DR 15559 Qinglu Lin Added round() methods. - * + * * * * @author mschenke @@ -850,7 +850,7 @@ public class PolygonUtil { List prepped = new ArrayList( geomList.size()); for (Geometry g : geomList) { - prepped.add(PreparedGeometryFactory.prepare(g)); + prepped.add(new PreparedGeometryCollection(g)); } GeometryFactory gf = warningArea.getFactory(); @@ -931,56 +931,54 @@ public class PolygonUtil { } } } - - public static void truncate(Listcoordinates, int decimalPlaces) { + + public static void truncate(List coordinates, int decimalPlaces) { for (Coordinate coordinate : coordinates) { truncate(coordinate, decimalPlaces); } } - + public static void truncate(Coordinate[] coordinates, int decimalPlaces) { for (Coordinate coordinate : coordinates) { truncate(coordinate, decimalPlaces); } } - + public static void truncate(Coordinate coordinate, int decimalPlaces) { double x = coordinate.x * Math.pow(10, decimalPlaces); double y = coordinate.y * Math.pow(10, decimalPlaces); - + x = x >= 0 ? Math.floor(x) : Math.ceil(x); y = y >= 0 ? Math.floor(y) : Math.ceil(y); - + coordinate.x = x / Math.pow(10, decimalPlaces); coordinate.y = y / Math.pow(10, decimalPlaces); } - public static void round(Listcoordinates, int decimalPlaces) { + public static void round(List coordinates, int decimalPlaces) { for (Coordinate coordinate : coordinates) { round(coordinate, decimalPlaces); } } - + public static void round(Coordinate[] coordinates, int decimalPlaces) { for (Coordinate coordinate : coordinates) { round(coordinate, decimalPlaces); } } - + /** - * round() - * Rounding coordinates, instead of truncating them. - * - * History - * 12/06/2012 DR 15559 Qinglu Lin Created. + * round() Rounding coordinates, instead of truncating them. + * + * History 12/06/2012 DR 15559 Qinglu Lin Created. */ public static void round(Coordinate coordinate, int decimalPlaces) { double x = coordinate.x * Math.pow(10, decimalPlaces); double y = coordinate.y * Math.pow(10, decimalPlaces); - + x = Math.round(x); y = Math.round(y); - + coordinate.x = x / Math.pow(10, decimalPlaces); coordinate.y = y / Math.pow(10, decimalPlaces); } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java index 5887eb290d..c7736358ac 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java @@ -24,13 +24,13 @@ import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.TimeZone; import java.util.regex.Matcher; @@ -40,10 +40,15 @@ import javax.measure.converter.UnitConverter; import javax.measure.unit.NonSI; import javax.measure.unit.SI; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.IMenuManager; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.PlatformUI; import org.geotools.geometry.jts.JTS; import org.geotools.referencing.GeodeticCalculator; @@ -60,6 +65,7 @@ import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration; import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData; import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialFactory; import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialMetadata; +import com.raytheon.uf.common.dataplugin.warning.gis.PreparedGeometryCollection; import com.raytheon.uf.common.dataplugin.warning.util.CountyUserData; import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil; import com.raytheon.uf.common.geospatial.DestinationGeodeticCalculator; @@ -118,7 +124,6 @@ import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.TopologyException; import com.vividsolutions.jts.geom.prep.PreparedGeometry; -import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; @@ -152,10 +157,10 @@ import com.vividsolutions.jts.io.WKTReader; * 12/13/2012 DR 15559 Qinglu Lin Added code to call WarngenUIState's adjustPolygon(). * 12/17/2012 DR 15571 Qinglu Lin For hydro products,futurePoints is null. Resolved an issue caused by trying to get * Coordinate[] from futurePoints. - * 12/18/2012 DR 15571 Qinglu Lin Resolved coordinate issue in TML line caused by clicking Restart button. + * 12/18/2012 DR 15571 Qinglu Lin Resolved coordinate issue in TML line caused by clicking Restart button. * 01/24/2013 DR 15723 Qinglu Lin Added initRemovedGids() and updated updateWarnedAreas() to prevent the removed * counties from being re-hatched. - * + * * * * @author mschenke @@ -183,6 +188,60 @@ public class WarngenLayer extends AbstractStormTrackResource { int nx, ny; } + private class CustomMaps extends Job { + + private Set customMaps = new HashSet(); + + private Set mapsToLoad; + + private MapManager manager; + + public CustomMaps() { + super("Loading WarnGen Maps"); + manager = MapManager.getInstance(descriptor); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + boolean done = false; + while (!done) { + Set toLoad = null; + synchronized (this) { + if (mapsToLoad != null) { + toLoad = mapsToLoad; + mapsToLoad = null; + } + } + + if (toLoad != null) { + for (String loaded : customMaps) { + manager.unloadMap(loaded); + } + + for (String load : toLoad) { + manager.loadMapByName(load); + } + + issueRefresh(); + } + + done = mapsToLoad == null; + } + return Status.OK_STATUS; + } + + public void loadCustomMaps(Collection maps) { + synchronized (this) { + mapsToLoad = new HashSet(maps); + } + schedule(); + } + + public void clearMaps() { + loadCustomMaps(new HashSet()); + } + } + private static Map siteMap = new HashMap(); private static Map timezoneMap = new HashMap(); @@ -222,7 +281,7 @@ public class WarngenLayer extends AbstractStormTrackResource { private boolean boxEditable = true; - private Map> loadedCustomMaps; + private CustomMaps customMaps; protected Mode lastMode = null; @@ -264,7 +323,7 @@ public class WarngenLayer extends AbstractStormTrackResource { super(resourceData, loadProperties, descriptor); displayState.displayType = DisplayType.POINT; getCapability(ColorableCapability.class).setColor(WHITE); - loadedCustomMaps = new HashMap>(); + customMaps = new CustomMaps(); try { dialogConfig = DialogConfiguration @@ -389,13 +448,7 @@ public class WarngenLayer extends AbstractStormTrackResource { @Override protected void disposeInternal() { - for (Entry> entry : loadedCustomMaps - .entrySet()) { - for (String map : entry.getValue()) { - MapManager.getInstance(entry.getKey()).unloadMap(map); - } - } - loadedCustomMaps.clear(); + customMaps.clearMaps(); super.disposeInternal(); @@ -436,7 +489,6 @@ public class WarngenLayer extends AbstractStormTrackResource { } super.initInternal(target); VizApp.runSync(new Runnable() { - @Override public void run() { createDialog(); @@ -497,17 +549,17 @@ public class WarngenLayer extends AbstractStormTrackResource { displayState.geomChanged = false; } if (warningAction == null || warningAction == WarningAction.NEW) { - // Initialize box - if (((configuration.isTrackEnabled() == false || configuration - .getPathcastConfig() == null) && this.displayState.displayType != DisplayType.POLY) - || frameCount == 1) { - createSquare(); - resetInitialFrame(); - } else { - redrawBoxFromTrack(); - } + // Initialize box + if (((configuration.isTrackEnabled() == false || configuration + .getPathcastConfig() == null) && this.displayState.displayType != DisplayType.POLY) + || frameCount == 1) { + createSquare(); + resetInitialFrame(); + } else { + redrawBoxFromTrack(); + } } else { - redrawBoxFromTrack(); + redrawBoxFromTrack(); } } @@ -750,7 +802,7 @@ public class WarngenLayer extends AbstractStormTrackResource { local); gd.attributes.put( GeospatialDataList.LOCAL_PREP_GEOM, - PreparedGeometryFactory.prepare(local)); + new PreparedGeometryCollection(local)); locals.add(local); } @@ -829,43 +881,11 @@ public class WarngenLayer extends AbstractStormTrackResource { String areaSource = config.getGeospatialConfig().getAreaSource(); geoData = siteMap.get(areaSource + "." + site); }// end synchronize - loadCustomMaps(descriptor, config); - this.configuration = config; - System.out.println("Time to init warngen config: " - + (System.currentTimeMillis() - t0)); - } + customMaps.loadCustomMaps(Arrays.asList(config.getMaps())); - protected void loadCustomMaps(MapDescriptor descriptor, - WarngenConfiguration config) { - if (config == null || descriptor == null) { - return; - } - long t1 = System.currentTimeMillis(); - MapManager mapManager = MapManager.getInstance(descriptor); - List maps = Arrays.asList(config.getMaps()); - Set loadedCustomMaps = this.loadedCustomMaps.get(descriptor); - if (loadedCustomMaps == null) { - loadedCustomMaps = new HashSet(); - this.loadedCustomMaps.put(descriptor, loadedCustomMaps); - } - Iterator it = loadedCustomMaps.iterator(); - while (it.hasNext()) { - String map = it.next(); - if (!maps.contains(map)) { - it.remove(); - mapManager.unloadMap(map); - } - } - for (String map : maps) { - if (!loadedCustomMaps.contains(map)) { - if (!mapManager.isMapLoaded(map)) { - mapManager.loadMapByName(map); - loadedCustomMaps.add(map); - } - } - } - System.out.println("Time to load custom maps: " - + (System.currentTimeMillis() - t1)); + this.configuration = config; + System.out.println("Total time to init warngen config = " + + (System.currentTimeMillis() - t0) + "ms"); } public GeospatialData[] getGeodataFeatures(String key) { @@ -1107,30 +1127,17 @@ public class WarngenLayer extends AbstractStormTrackResource { dialog = new WarngenDialog(PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getShell(), this); dialog.open(); - addDialogDisposeListener(descriptor); - } else { - showDialog(true); - } - } - - public void addDialogDisposeListener(final MapDescriptor descriptor) { - if (dialog != null) { - dialog.getShell().addDisposeListener(new DisposeListener() { + dialog.addListener(SWT.Dispose, new Listener() { @Override - public void widgetDisposed(DisposeEvent e) { + public void handleEvent(Event event) { descriptor.getResourceList().removeRsc(WarngenLayer.this); } }); + } else { + showDialog(true); } } - @Override - public void setDescriptor(MapDescriptor descriptor) { - super.setDescriptor(descriptor); - addDialogDisposeListener(descriptor); - loadCustomMaps(descriptor, configuration); - } - /** * Show the WarnGen dialog and move it to the front. */ @@ -1625,15 +1632,15 @@ public class WarngenLayer extends AbstractStormTrackResource { if (hatched != null) { // DR 15559 Coordinate[] coords = hatched.getCoordinates(); - PolygonUtil.round(coords, 2); - state.adjustPolygon(coords); - GeometryFactory gf = new GeometryFactory(); - LinearRing lr = gf.createLinearRing(coords); - state.setWarningPolygon(gf.createPolygon(lr, null)); - updateWarnedAreas(true, true); - issueRefresh(); - // End of DR 15559 - state.snappedToArea = true; + PolygonUtil.round(coords, 2); + state.adjustPolygon(coords); + GeometryFactory gf = new GeometryFactory(); + LinearRing lr = gf.createLinearRing(coords); + state.setWarningPolygon(gf.createPolygon(lr, null)); + updateWarnedAreas(true, true); + issueRefresh(); + // End of DR 15559 + state.snappedToArea = true; } System.out.println("Time to createWarningPolygon: " + (System.currentTimeMillis() - t0) + "ms"); @@ -1852,16 +1859,20 @@ public class WarngenLayer extends AbstractStormTrackResource { Coordinate[] cc = null; switch (stormTrackState.displayType) { case POINT: - cc = new Coordinate[] { stormTrackState.futurePoints == null ? stormTrackState.dragMePoint - .getCoordinate() : stormTrackState.futurePoints[0].coord }; - if (warningAction == null || warningAction == WarningAction.NEW || warningAction == WarningAction.CON - || warningAction == WarningAction.CAN) { - Coordinate coord = new Coordinate(stormTrackState.dragMePoint.getCoordinate()); - DataTime currentDataTime = new DataTime(SimulatedTime.getSystemTime().getTime()); - if (stormTrackState.compuateCurrentStormCenter(coord,currentDataTime)) - cc = new Coordinate[] {coord}; - } - break; + cc = new Coordinate[] { stormTrackState.futurePoints == null ? stormTrackState.dragMePoint + .getCoordinate() : stormTrackState.futurePoints[0].coord }; + if (warningAction == null || warningAction == WarningAction.NEW + || warningAction == WarningAction.CON + || warningAction == WarningAction.CAN) { + Coordinate coord = new Coordinate( + stormTrackState.dragMePoint.getCoordinate()); + DataTime currentDataTime = new DataTime(SimulatedTime + .getSystemTime().getTime()); + if (stormTrackState.compuateCurrentStormCenter(coord, + currentDataTime)) + cc = new Coordinate[] { coord }; + } + break; case POLY: Coordinate[] polyPoints = stormTrackState.dragMeLine .getCoordinates(); @@ -2378,9 +2389,9 @@ public class WarngenLayer extends AbstractStormTrackResource { + e.getLocalizedMessage(), e); } } - + public void setWarningAction(WarningAction warningAction) { - this.warningAction = warningAction; + this.warningAction = warningAction; } public void initRemovedGids() { diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/CurrentWarnings.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/CurrentWarnings.java index dab39fd1fd..d82e4d996b 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/CurrentWarnings.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/CurrentWarnings.java @@ -20,6 +20,7 @@ package com.raytheon.viz.warngen.util; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -37,8 +38,10 @@ import com.raytheon.uf.common.dataplugin.warning.UGCZone; import com.raytheon.uf.common.dataplugin.warning.WarningRecord; import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction; import com.raytheon.uf.common.dataplugin.warning.util.AnnotationUtil; +import com.raytheon.uf.common.dataquery.requests.DbQueryRequest; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; import com.raytheon.uf.common.site.SiteMap; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -46,10 +49,8 @@ import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.viz.core.alerts.AlertMessage; -import com.raytheon.uf.viz.core.catalog.LayerProperty; -import com.raytheon.uf.viz.core.catalog.ScriptCreator; -import com.raytheon.uf.viz.core.comm.Connector; -import com.raytheon.uf.viz.core.rsc.ResourceType; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.requests.ThriftClient; import com.raytheon.viz.alerts.IAlertObserver; import com.raytheon.viz.alerts.observers.ProductAlertObserver; import com.raytheon.viz.core.mode.CAVEMode; @@ -187,7 +188,8 @@ public class CurrentWarnings { * @param phenSigs * @return */ - public List getCorrectableWarnings(AbstractWarningRecord warnRec) { + public List getCorrectableWarnings( + AbstractWarningRecord warnRec) { List rval = new ArrayList(); Calendar current = Calendar.getInstance(); Calendar end = Calendar.getInstance(); @@ -197,24 +199,28 @@ public class CurrentWarnings { for (AbstractWarningRecord warning : records) { String phensig = warning.getPhensig(); String etn = warning.getEtn(); - - if (warnRec.getPhensig().equals(phensig) && warnRec.getEtn().equals(etn)) { - WarningAction action = WarningAction.valueOf(warning.getAct()); + + if (warnRec.getPhensig().equals(phensig) + && warnRec.getEtn().equals(etn)) { + WarningAction action = WarningAction.valueOf(warning + .getAct()); end.setTime(warning.getStartTime().getTime()); end.add(Calendar.MINUTE, 10); - TimeRange t = new TimeRange(warning.getStartTime().getTime(), - end.getTime()); - if ((action == WarningAction.NEW || action == WarningAction.CON || action == WarningAction.EXT) + TimeRange t = new TimeRange(warning.getStartTime() + .getTime(), end.getTime()); + if ((action == WarningAction.NEW + || action == WarningAction.CON || action == WarningAction.EXT) && t.contains(current.getTime())) { rval.add(warning); - } else if (action == WarningAction.CAN || action == WarningAction.EXP) { + } else if (action == WarningAction.CAN + || action == WarningAction.EXP) { rval.clear(); return rval; } } } } - + return rval; } @@ -253,7 +259,7 @@ public class CurrentWarnings { for (AbstractWarningRecord warning : warnings) { if (getAction(warning.getAct()) == WarningAction.CON) { if (rval != null) { - //rval.setAct("CON"); + // rval.setAct("CON"); rval.setGeometry(warning.getGeometry()); rval.setCountyheader(warning.getCountyheader()); rval.setUgczones(warning.getUgczones()); @@ -421,7 +427,10 @@ public class CurrentWarnings { Map constraints = new HashMap(); constraints.put("officeid", new RequestConstraint(officeId)); + long t0 = System.currentTimeMillis(); List warnings = requestRecords(constraints); + System.out.println("Time to request CurrentWarnings records: " + + (System.currentTimeMillis() - t0) + "ms"); processRecords(warnings); } @@ -472,6 +481,10 @@ public class CurrentWarnings { } } + if (dataURIs.size() == 0) { + return; + } + Map constraints = new HashMap(); RequestConstraint constraint = new RequestConstraint(null, ConstraintType.IN); @@ -534,25 +547,16 @@ public class CurrentWarnings { private static List requestRecords( Map constraints) { List newRecords = new ArrayList(); - Object[] resp; - LayerProperty lp = new LayerProperty(); + try { - String tableName = AnnotationUtil.getTableName(getWarningClass()); - - constraints.put("pluginName", new RequestConstraint(tableName)); - lp.setDesiredProduct(ResourceType.PLAN_VIEW); - lp.setEntryQueryParameters(constraints, false); - - lp.setNumberOfImages(9999); - - String script = ScriptCreator.createScript(lp); - if (script != null) { - resp = Connector.getInstance().connect(script, null, 60000); - for (int i = 0; i < resp.length; i++) { - newRecords.add((AbstractWarningRecord) resp[i]); - } - } - } catch (Exception e) { + DbQueryRequest request = new DbQueryRequest(); + request.setConstraints(constraints); + request.setEntityClass(getWarningClass()); + DbQueryResponse response = (DbQueryResponse) ThriftClient + .sendRequest(request); + newRecords.addAll(Arrays.asList(response + .getEntityObjects(AbstractWarningRecord.class))); + } catch (VizException e) { statusHandler.handle(Priority.PROBLEM, "Error retreiving warnings", e); } diff --git a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java index bc02f41e81..d4257aede8 100644 --- a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java +++ b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java @@ -22,8 +22,8 @@ package com.raytheon.viz.warnings.rsc; import java.util.ArrayList; import java.util.Calendar; -import java.util.Date; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.Timer; import java.util.TimerTask; @@ -33,14 +33,10 @@ import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord; import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.DataTime; -import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.viz.core.IGraphicsTarget; -import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; -import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.IWireframeShape; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; import com.raytheon.viz.core.rsc.jts.JTSCompiler; @@ -70,132 +66,38 @@ import com.vividsolutions.jts.geom.Geometry; public class WarningsResource extends AbstractWWAResource { - protected static class RepaintHeartbeat extends TimerTask { + protected static class RefreshTimerTask extends TimerTask { - private final HashSet> resourceSet = new HashSet>(); - - private boolean cancelled = false; - - public RepaintHeartbeat() { - - } - - /** - * copy resources from old task, just in case some were added after it - * should have been replaced (threads are fun) - **/ - public void copyResourceSet(RepaintHeartbeat oldTask) { - // copy resources, in case one was added after a cancel - Set> oldResourceSet = oldTask - .getResourceSet(); - synchronized (oldResourceSet) { - for (AbstractVizResource rsc : oldResourceSet) { - this.addResource(rsc); - } - } - } - - public Set> getResourceSet() { - return resourceSet; - } + private final Set resourceSet = new HashSet(); @Override public void run() { - // get the unique displays from all the added resources - ArrayList displaysToRefresh = new ArrayList( - 1); + List rscs; synchronized (resourceSet) { - for (AbstractVizResource rsc : resourceSet) { - try { - IRenderableDisplay disp = rsc.getDescriptor() - .getRenderableDisplay(); - if (!displaysToRefresh.contains(disp)) { - displaysToRefresh.add(disp); - } - } catch (Exception e) { - statusHandler - .handle(Priority.PROBLEM, - "Encountered error during Warnings Heartbeat, continuing with other Warnings ", - e); - } - } + rscs = new ArrayList(resourceSet); } - - // create an array with final modifier - final IRenderableDisplay[] refreshList = displaysToRefresh - .toArray(new IRenderableDisplay[displaysToRefresh.size()]); - - // execute refersh in UI thread - VizApp.runAsync(new Runnable() { - - @Override - public void run() { - for (IRenderableDisplay disp : refreshList) { - disp.refresh(); - } - } - - }); - - // cancel the task if there are no more resources - boolean cancel = false; - synchronized (resourceSet) { - if (resourceSet.size() < 1) { - cancel = true; - } - } - - if (cancel) { - doCancel(); + for (WarningsResource rsc : rscs) { + rsc.issueRefresh(); } } - public void addResource(AbstractVizResource rsc) { - // if task has no resources then it needs to be started when the - // first is added - boolean start = false; + public void addResource(WarningsResource rsc) { synchronized (resourceSet) { - // if this is the first resource added to an empty set start the - // timer - if (resourceSet.size() < 1) { - start = true; - } resourceSet.add(rsc); } - if (start) { - WarningsResource.scheduleHeartBeat(); - } } - public void removeResource(AbstractVizResource rsc) { + public void removeResource(WarningsResource rsc) { synchronized (resourceSet) { resourceSet.remove(rsc); - // cancel the task if there are no more resources - if (resourceSet.size() < 1) { - doCancel(); - } } } - private void doCancel() { - synchronized (heartBeatChangeLock) { - if (cancelled == false) { - cancelled = true; - heartBeatTimer.cancel(); - heartBeatTask = new RepaintHeartbeat(); - heartBeatTimer = new Timer(); - heartBeatTask.copyResourceSet(this); - } - } - } } - /** lock when changing heartBeatTask **/ - protected static final Object heartBeatChangeLock = new Object(); + protected static RefreshTimerTask refreshTask; - protected static RepaintHeartbeat heartBeatTask = null; - - protected static Timer heartBeatTimer = null; + protected static Timer refreshTimer; /** * Constructor @@ -207,14 +109,13 @@ public class WarningsResource extends AbstractWWAResource { @Override protected void initInternal(IGraphicsTarget target) throws VizException { - DataTime earliest = this.descriptor.getFramesInfo().getFrameTimes()[0]; - requestData(earliest); - synchronized (heartBeatChangeLock) { - if (heartBeatTask == null) { - heartBeatTask = new RepaintHeartbeat(); - } - heartBeatTask.addResource(this); + FramesInfo info = descriptor.getFramesInfo(); + DataTime[] times = info.getFrameTimes(); + if (times != null && times.length > 0) { + // Request data for "earliest" time + requestData(times[0]); } + scheduleRefreshTask(this); } /* @@ -224,9 +125,7 @@ public class WarningsResource extends AbstractWWAResource { */ @Override protected void disposeInternal() { - synchronized (heartBeatChangeLock) { - heartBeatTask.removeResource(this); - } + cancelRefreshTask(this); for (WarningEntry entry : entryMap.values()) { if (entry.shadedShape != null) { entry.shadedShape.dispose(); @@ -404,43 +303,45 @@ public class WarningsResource extends AbstractWWAResource { } + /** + * Cancel the heart beat timer task + * + * @param resource + */ + protected static void cancelRefreshTask(WarningsResource resource) { + synchronized (RefreshTimerTask.class) { + if (refreshTask != null) { + refreshTask.removeResource(resource); + if (refreshTask.resourceSet.isEmpty()) { + refreshTimer.cancel(); + refreshTimer = null; + refreshTask = null; + } + } + } + } + /** * schedule the heart beat for the next minute */ - protected static void scheduleHeartBeat() { - // get simulated time - Date currentTime = SimulatedTime.getSystemTime().getTime(); - // get a calendar - Calendar now = Calendar.getInstance(); - // set calendar time to simulated time - now.setTime(currentTime); - // add one to the minutes field - now.add(Calendar.MINUTE, 1); - // reset second and milisecond to 0 - now.set(Calendar.SECOND, 0); - now.set(Calendar.MILLISECOND, 0); - // schedule task to fire every minute - synchronized (heartBeatChangeLock) { - try { - if (heartBeatTimer == null) { - heartBeatTimer = new Timer(); - } - // schedule on the minute every minute - heartBeatTimer.schedule(heartBeatTask, now.getTime(), - 1 * 60 * 1000); - } catch (Exception e) { - try { - heartBeatTimer.cancel(); - } catch (Exception e2) { - // ignore, we just want to make sure the timer is cancelled - } finally { - // create a new task if there was an error when scheduling - heartBeatTask = new RepaintHeartbeat(); - heartBeatTimer = new Timer(); - } - statusHandler.handle(Priority.SIGNIFICANT, - "Error scheduling warnings heart beat ", e); + protected static void scheduleRefreshTask(WarningsResource resource) { + synchronized (RefreshTimerTask.class) { + if (refreshTask == null) { + refreshTimer = new Timer(true); + refreshTask = new RefreshTimerTask(); + + // get a calendar + Calendar now = Calendar.getInstance(); + // add one to the minutes field + now.add(Calendar.MINUTE, 1); + // reset second and milisecond to 0 + now.set(Calendar.SECOND, 0); + now.set(Calendar.MILLISECOND, 0); + + refreshTimer.scheduleAtFixedRate(refreshTask, now.getTime(), + 60 * 1000); } + refreshTask.addResource(resource); } } diff --git a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WatchesResource.java b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WatchesResource.java index 330b178d6b..ae2b363dc2 100644 --- a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WatchesResource.java +++ b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WatchesResource.java @@ -192,6 +192,9 @@ public class WatchesResource extends AbstractWWAResource { JTSCompiler jtsCompiler = new JTSCompiler(ss, null, this.descriptor, PointStyle.CROSS); jtsCompiler.handle(geo, color); + if (record.getPhen() == null) { + return; + } ss.setFillPattern(FillPatterns.getGLPattern(record.getPhen() .equals("TO") ? "VERTICAL" : "HORIZONTAL")); ss.compile(); diff --git a/cots/org.junit/.classpath b/cots/org.junit/.classpath index 7363c566f4..e8a366c3b4 100644 --- a/cots/org.junit/.classpath +++ b/cots/org.junit/.classpath @@ -1,5 +1,7 @@ + + @@ -10,6 +12,5 @@ - diff --git a/cots/org.junit/META-INF/MANIFEST.MF b/cots/org.junit/META-INF/MANIFEST.MF index 7f2d8e6aba..e357195e12 100644 --- a/cots/org.junit/META-INF/MANIFEST.MF +++ b/cots/org.junit/META-INF/MANIFEST.MF @@ -11,7 +11,8 @@ Bundle-ClassPath: jmock-2.0.0.jar, mockito-all-1.9.0.jar, objenesis-1.2.jar, powermock-mockito-1.4.12-full.jar, - junit-4.10.jar + hamcrest-all-1.3.jar, + junit-dep-4.11.jar Export-Package: javassist, javassist.bytecode, javassist.bytecode.analysis, @@ -43,8 +44,28 @@ Export-Package: javassist, net.sf.cglib.transform.impl, net.sf.cglib.util, org.hamcrest, + org.hamcrest.beans, + org.hamcrest.collection, org.hamcrest.core, + org.hamcrest.generator, + org.hamcrest.generator.config, + org.hamcrest.generator.qdox, + org.hamcrest.generator.qdox.ant, + org.hamcrest.generator.qdox.directorywalker, + org.hamcrest.generator.qdox.junit, + org.hamcrest.generator.qdox.model, + org.hamcrest.generator.qdox.model.annotation, + org.hamcrest.generator.qdox.model.util, + org.hamcrest.generator.qdox.parser, + org.hamcrest.generator.qdox.parser.impl, + org.hamcrest.generator.qdox.parser.structs, + org.hamcrest.generator.qdox.tools, + org.hamcrest.integration, org.hamcrest.internal, + org.hamcrest.number, + org.hamcrest.object, + org.hamcrest.text, + org.hamcrest.xml, org.jmock, org.jmock.api, org.jmock.example.qcon, diff --git a/cots/org.junit/build.properties b/cots/org.junit/build.properties index da97b1e7e3..4679b8281a 100644 --- a/cots/org.junit/build.properties +++ b/cots/org.junit/build.properties @@ -8,4 +8,5 @@ bin.includes = META-INF/,\ mockito-all-1.9.0.jar,\ objenesis-1.2.jar,\ powermock-mockito-1.4.12-full.jar,\ - junit-4.10.jar + hamcrest-all-1.3.jar,\ + junit-dep-4.11.jar diff --git a/cots/org.junit/hamcrest-all-1.3-sources.jar b/cots/org.junit/hamcrest-all-1.3-sources.jar new file mode 100644 index 0000000000..77dfc35d1f Binary files /dev/null and b/cots/org.junit/hamcrest-all-1.3-sources.jar differ diff --git a/cots/org.junit/hamcrest-all-1.3.jar b/cots/org.junit/hamcrest-all-1.3.jar new file mode 100644 index 0000000000..6f62ba00c7 Binary files /dev/null and b/cots/org.junit/hamcrest-all-1.3.jar differ diff --git a/cots/org.junit/junit-4.10-src.jar b/cots/org.junit/junit-4.10-src.jar deleted file mode 100644 index 1449d28b5b..0000000000 Binary files a/cots/org.junit/junit-4.10-src.jar and /dev/null differ diff --git a/cots/org.junit/junit-4.10.jar b/cots/org.junit/junit-4.10.jar deleted file mode 100644 index bf5c0b9c6a..0000000000 Binary files a/cots/org.junit/junit-4.10.jar and /dev/null differ diff --git a/cots/org.junit/junit-4.11-src.jar b/cots/org.junit/junit-4.11-src.jar new file mode 100644 index 0000000000..80801569a5 Binary files /dev/null and b/cots/org.junit/junit-4.11-src.jar differ diff --git a/cots/org.junit/junit-dep-4.11.jar b/cots/org.junit/junit-dep-4.11.jar new file mode 100644 index 0000000000..93c717aa8a Binary files /dev/null and b/cots/org.junit/junit-dep-4.11.jar differ diff --git a/deltaScripts/13.2.1/aggregateRecordGroupingLength.sh b/deltaScripts/13.2.1/aggregateRecordGroupingLength.sh new file mode 100644 index 0000000000..8be0366f68 --- /dev/null +++ b/deltaScripts/13.2.1/aggregateRecordGroupingLength.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +SQL_SCRIPT="increaseAggregateRecordGroupingLength.sql" + +# ensure that the sql script is present +if [ ! -f ${SQL_SCRIPT} ]; then + echo "ERROR: the required sql script - ${SQL_SCRIPT} was not found." + echo "FATAL: the update has failed!" + exit 1 +fi + +echo "INFO: update started - increasing the size of the aggregate.grouping column" + +# run the update +/awips2/psql/bin/psql -U awips -d metadata -f ${SQL_SCRIPT} +if [ $? -ne 0 ]; then + echo "FATAL: the update has failed!" + exit 1 +fi + +echo "INFO: the update has completed successfully!" + +exit 0 diff --git a/deltaScripts/13.2.1/convertAggregateRecordGroupToXml.sh b/deltaScripts/13.2.1/convertAggregateRecordGroupToXml.sh new file mode 100644 index 0000000000..556254619a --- /dev/null +++ b/deltaScripts/13.2.1/convertAggregateRecordGroupToXml.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +SQL_SCRIPT="convertAggregateRecordGroupToXml.sql" + +# ensure that the sql script is present +if [ ! -f ${SQL_SCRIPT} ]; then + echo "ERROR: the required sql script - ${SQL_SCRIPT} was not found." + echo "FATAL: the update has failed!" + exit 1 +fi + +echo "INFO: update started - converting the aggregate.grouping column to xml" + +# run the update +/awips2/psql/bin/psql -U awips -d metadata -f ${SQL_SCRIPT} +if [ $? -ne 0 ]; then + echo "FATAL: the update has failed!" + exit 1 +fi + +echo "INFO: the update has completed successfully!" + +exit 0 diff --git a/deltaScripts/13.2.1/convertAggregateRecordGroupToXml.sql b/deltaScripts/13.2.1/convertAggregateRecordGroupToXml.sql new file mode 100644 index 0000000000..424de941cf --- /dev/null +++ b/deltaScripts/13.2.1/convertAggregateRecordGroupToXml.sql @@ -0,0 +1,38 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +\set ON_ERROR_STOP 1 +\connect metadata; + +-- Start a transaction +BEGIN; + +-- Temporarily replace dashes in pluginName rows with @@@ +update events.aggregate set grouping = regexp_replace(grouping, 'pluginName:(.*?)-(.*)', E'pluginName:\\1@@@\\2', 'g'); + +-- Convert to XML format +update events.aggregate set grouping = regexp_replace(grouping, ':', '" value="', 'g'); +update events.aggregate set grouping = regexp_replace(grouping, '-', '"/>'; + +-- Restore dashes from @@@ +update events.aggregate set grouping = regexp_replace(grouping, ' * * @author bphillip @@ -77,8 +85,19 @@ public class D2DParmIdCache { private static final Pattern RangeFilter = Pattern .compile("(.*?)\\d{1,2}hr"); + private static final Map WIND_COMP_PARMS; + static { + WIND_COMP_PARMS = new HashMap(); + WIND_COMP_PARMS.put("uw", "vw"); + WIND_COMP_PARMS.put("vw", "uw"); + WIND_COMP_PARMS.put("ws", "wd"); + WIND_COMP_PARMS.put("wd", "ws"); + } + /** Map containing the ParmIDs */ - private Map> parmIds; + private Map> parmIds; + + private Map> windComps; private static D2DParmIdCache instance; @@ -93,7 +112,8 @@ public class D2DParmIdCache { * Constructs a new D2DParmIdCache */ public D2DParmIdCache() { - parmIds = new HashMap>(); + parmIds = new HashMap>(); + windComps = new HashMap>(); } /** @@ -140,53 +160,18 @@ public class D2DParmIdCache { } private void putParmIDInternal(ParmID parmId) { + DatabaseID dbId = parmId.getDbId(); synchronized (parmIds) { + Set dbParms = parmIds.get(dbId); // Add the database entry to the map if it does not exist - if (!parmIds.containsKey(parmId.getDbId().toString())) { - parmIds.put(parmId.getDbId().toString(), new HashSet()); + if (dbParms == null) { + dbParms = new HashSet(); + parmIds.put(dbId, dbParms); } - // Insert the ParmID into the map - String parmStr = parmId.toString(); - // Ensure that the staticTopo parameter has the correct - // capitalization, or the smart init scripts will not be able to - // find it - String parmName = parmId.getParmName(); - if (parmName.equalsIgnoreCase("staticTopo")) { - parmStr = parmStr.replace("statictopo", "staticTopo"); - } else if (parmName.equalsIgnoreCase("staticspacing")) { - parmStr = parmStr.replace("staticspacing", "staticSpacing"); - } else if (parmName.equalsIgnoreCase("staticXspacing")) { - parmStr = parmStr.replace("staticxspacing", "staticXspacing"); - } else if (parmName.equalsIgnoreCase("staticYspacing")) { - parmStr = parmStr.replace("staticyspacing", "staticYspacing"); - } else if (parmName.equalsIgnoreCase("staticCoriolis")) { - parmStr = parmStr.replace("staticcoriolis", "staticCoriolis"); - } else { - String gfeParamName = null; - try { - gfeParamName = ParameterMapper.getInstance().lookupAlias( - parmId.getParmName(), "gfeParamName"); - } catch (MultipleMappingException e) { - statusHandler.handle(Priority.WARN, - e.getLocalizedMessage(), e); - gfeParamName = e.getArbitraryMapping(); - } - parmStr = parmStr.replaceFirst( - parmId.getParmName(), - gfeParamName); - } - parmIds.get(parmId.getDbId().toString()).add(parmStr); - } - } - /** - * Places a parmId into the cache - * - * @param parmId - * String representation of a ParmID - */ - public void putParmID(String parmId) { - putParmID(new ParmID(parmId)); + // Insert the ParmID into the map + dbParms.add(parmId); + } } /** @@ -209,18 +194,10 @@ public class D2DParmIdCache { * @return The ParmIDs in the given DatabaseID */ public List getParmIDs(DatabaseID dbId) { - Set parmStrings = null; + List parms = Collections.emptyList(); synchronized (parmIds) { if (parmIds.containsKey(dbId.toString())) { - parmStrings = new HashSet(parmIds.get(dbId.toString())); - } - } - - List parms = Collections.emptyList(); - if (parmStrings != null) { - parms = new ArrayList(parmStrings.size()); - for (String parmStr : parmStrings) { - parms.add(new ParmID(parmStr)); + parms = new ArrayList(parmIds.get(dbId)); } } return parms; @@ -244,14 +221,9 @@ public class D2DParmIdCache { * @return The list of DatabaseIDs */ public List getDatabaseIDs() { - Set dbStrs; + List dbIds = null; synchronized (parmIds) { - dbStrs = new HashSet(parmIds.keySet()); - } - - List dbIds = new ArrayList(dbStrs.size()); - for (String dbId : dbStrs) { - dbIds.add(new DatabaseID(dbId)); + dbIds = new ArrayList(parmIds.keySet()); } return dbIds; } @@ -382,6 +354,19 @@ public class D2DParmIdCache { for (DatabaseID dbId : dbsToRemove) { GridParmManager.removeDbFromMap(dbId); } + // purge the windComps + List wcToRemove = new ArrayList(); + synchronized (windComps) { + for (ParmID id : windComps.keySet()) { + if (dbsToRemove.contains(id.getDbId())) { + wcToRemove.add(id); + } + } + for (ParmID id : wcToRemove) { + windComps.remove(id); + } + } + statusHandler.handle(Priority.EVENTA, "Total time to build D2DParmIdCache for " + siteID + " took " + (System.currentTimeMillis() - start) @@ -397,7 +382,7 @@ public class D2DParmIdCache { public long getSize() { long size = 0; synchronized (parmIds) { - for (Set parms : parmIds.values()) { + for (Set parms : parmIds.values()) { size += parms.size(); } } @@ -410,4 +395,63 @@ public class D2DParmIdCache { buildCache(null); } } + + public void processGridUpdateNotification(GridUpdateNotification gun) { + ParmID parmId = gun.getParmId(); + + String otherCompName = WIND_COMP_PARMS.get(parmId.getParmName()); + if (otherCompName == null) { + // if it's not a wind component just add it to the cache + putParmID(parmId); + } else { + Set windTrs = null; + synchronized (windComps) { + // add this parms times to windComps map + Set trs = windComps.get(parmId); + if (trs == null) { + trs = new HashSet(); + windComps.put(parmId, trs); + } + trs.addAll(gun.getHistories().keySet()); + + // get the other components times + ParmID otherCompId = new ParmID(otherCompName, + parmId.getDbId(), parmId.getParmLevel()); + Set otherTrs = windComps.get(otherCompId); + + // if we have both components + if (otherTrs != null) { + // find times where we have both components + windTrs = new HashSet(trs); + windTrs.retainAll(otherTrs); + + // remove the matching times since we don't need them + // anymore + trs.removeAll(windTrs); + otherTrs.removeAll(windTrs); + } + } + + // if we found any matching times for both components + if (windTrs != null && !windTrs.isEmpty()) { + // add the wind parmId to the cache + ParmID windId = new ParmID("wind", parmId.getDbId(), + parmId.getParmLevel()); + putParmID(windId); + + // create GridUpdateNotifications for the wind parm + Map> history = new HashMap>(); + ArrayList guns = new ArrayList( + windTrs.size()); + for (TimeRange tr : windTrs) { + history.put(tr, Arrays.asList(new GridDataHistory( + GridDataHistory.OriginType.INITIALIZED, windId, tr, + null, (WsId) null))); + guns.add(new GridUpdateNotification(windId, tr, history, + null, windId.getDbId().getSiteId())); + } + SendNotifications.send(guns); + } + } + } } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/cache/d2dparms/D2DParmIdFilter.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/cache/d2dparms/D2DParmIdFilter.java index eb523b9f93..c7096adedb 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/cache/d2dparms/D2DParmIdFilter.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/cache/d2dparms/D2DParmIdFilter.java @@ -34,7 +34,9 @@ import com.raytheon.uf.common.dataplugin.gfe.server.notify.GridUpdateNotificatio * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 1/10/09 1674 bphillip Initial creation - * 10/06/09 3172 njensen Based on grib notification + * 10/06/09 3172 njensen Based on grib notification + * 01/18/13 #1504 randerso Changed to send full GridUpdateNotification + * to D2DParmIdCache * * * @@ -53,8 +55,8 @@ public class D2DParmIdFilter { public void updateParmIdCache(List notifications) { for (GfeNotification notify : notifications) { if (notify instanceof GridUpdateNotification) { - D2DParmIdCache.getInstance().putParmID( - ((GridUpdateNotification) notify).getParmId()); + D2DParmIdCache.getInstance().processGridUpdateNotification( + (GridUpdateNotification) notify); } } } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFEDao.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFEDao.java index 967a62f588..04ff02e012 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFEDao.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFEDao.java @@ -105,9 +105,11 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery; * 08/07/09 #2763 njensen Refactored queryByD2DParmId * 09/10/12 DR15137 ryu Changed for MOSGuide D2D mxt/mnt grids for consistency * with A1. - * 10/10/12 #1260 randerso Added check to ensure db can be created before + * 10/10/12 #1260 randerso Added check to ensure db can be created before * adding it to the inventory * 12/06/12 #1394 rjpeter Optimized D2D grid access. + * 01/21/12 #1504 randerso Back ported change to use ParameterMapper into 13.1.2 + * * * * @author bphillip @@ -321,13 +323,13 @@ public class GFEDao extends DefaultPluginDao { } if (sess != null) { try { - sess.close(); + sess.close(); } catch (Exception e) { statusHandler.error( "Error occurred closing database session", e); - } } } + } return failedToSave.toArray(new GFERecord[failedToSave.size()]); @@ -460,9 +462,9 @@ public class GFEDao extends DefaultPluginDao { dataStore.delete(groupsToDelete); if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { - statusHandler.handle(Priority.DEBUG, - "Deleted: " + Arrays.toString(groupsToDelete) - + " from " + hdf5File.getName()); + statusHandler.handle(Priority.DEBUG, + "Deleted: " + Arrays.toString(groupsToDelete) + + " from " + hdf5File.getName()); } } catch (Exception e) { statusHandler.handle( @@ -657,10 +659,10 @@ public class GFEDao extends DefaultPluginDao { s = getHibernateTemplate().getSessionFactory().openSession(); // TODO: clean up so we only make one db query SortedMap rawTimes = queryByD2DParmId(id, s); - List gribTimes = new ArrayList(); + List gribTimes = new ArrayList(); for (DataTime dt : rawTimes.keySet()) { gribTimes.add(dt.getValidPeriod()); - } + } try { if (isMos(id)) { @@ -670,26 +672,26 @@ public class GFEDao extends DefaultPluginDao { .getValidPeriod(); TimeRange time = info.getTimeConstraints() .constraintTime(gribTime.getEnd()); - if (timeRange.getEnd().equals(time.getEnd()) - || !info.getTimeConstraints().anyConstraints()) { + if (timeRange.getEnd().equals(time.getEnd()) + || !info.getTimeConstraints().anyConstraints()) { GridRecord retVal = (GridRecord) s.get( GridRecord.class, timeEntry.getValue()); - retVal.setPluginName(GridConstants.GRID); - return retVal; - } + retVal.setPluginName(GridConstants.GRID); + return retVal; + } } } else if (D2DGridDatabase.isNonAccumDuration(id, gribTimes)) { for (Map.Entry timeEntry : rawTimes .entrySet()) { TimeRange gribTime = timeEntry.getKey() .getValidPeriod(); - if (timeRange.getStart().equals(gribTime.getEnd()) - || timeRange.equals(gribTime)) { + if (timeRange.getStart().equals(gribTime.getEnd()) + || timeRange.equals(gribTime)) { GridRecord retVal = (GridRecord) s.get( GridRecord.class, timeEntry.getValue()); - retVal.setPluginName(GridConstants.GRID); - return retVal; - } + retVal.setPluginName(GridConstants.GRID); + return retVal; + } } } else { for (Map.Entry timeEntry : rawTimes @@ -698,15 +700,15 @@ public class GFEDao extends DefaultPluginDao { .getValidPeriod(); TimeRange time = info.getTimeConstraints() .constraintTime(gribTime.getStart()); - if ((timeRange.getStart().equals(time.getStart()) || !info - .getTimeConstraints().anyConstraints())) { + if ((timeRange.getStart().equals(time.getStart()) || !info + .getTimeConstraints().anyConstraints())) { GridRecord retVal = (GridRecord) s.get( GridRecord.class, timeEntry.getValue()); - retVal.setPluginName(GridConstants.GRID); - return retVal; - } + retVal.setPluginName(GridConstants.GRID); + return retVal; } } + } } catch (GfeConfigurationException e) { throw new DataAccessLayerException( "Error getting configuration for " @@ -720,7 +722,7 @@ public class GFEDao extends DefaultPluginDao { statusHandler.error( "Error occurred closing database session", e); } - } + } } return null; @@ -743,48 +745,48 @@ public class GFEDao extends DefaultPluginDao { @SuppressWarnings("unchecked") public SortedMap queryByD2DParmId(ParmID id, Session s) throws DataAccessLayerException { - String levelName = GridTranslator.getLevelName(id.getParmLevel()); + String levelName = GridTranslator.getLevelName(id.getParmLevel()); double[] levelValues = GridTranslator.getLevelValue(id.getParmLevel()); - boolean levelOnePresent = (levelValues[0] != Level - .getInvalidLevelValue()); - boolean levelTwoPresent = (levelValues[1] != Level - .getInvalidLevelValue()); - Level level = null; + boolean levelOnePresent = (levelValues[0] != Level + .getInvalidLevelValue()); + boolean levelTwoPresent = (levelValues[1] != Level + .getInvalidLevelValue()); + Level level = null; - // to have a level 2, must have a level one - try { - if (levelOnePresent && levelTwoPresent) { - level = LevelFactory.getInstance().getLevel(levelName, - levelValues[0], levelValues[1]); - } else if (levelOnePresent) { - level = LevelFactory.getInstance().getLevel(levelName, - levelValues[0]); - } else { - level = LevelFactory.getInstance().getLevel(levelName, 0.0); + // to have a level 2, must have a level one + try { + if (levelOnePresent && levelTwoPresent) { + level = LevelFactory.getInstance().getLevel(levelName, + levelValues[0], levelValues[1]); + } else if (levelOnePresent) { + level = LevelFactory.getInstance().getLevel(levelName, + levelValues[0]); + } else { + level = LevelFactory.getInstance().getLevel(levelName, 0.0); + } + } catch (CommunicationException e) { + logger.error(e.getLocalizedMessage(), e); } - } catch (CommunicationException e) { - logger.error(e.getLocalizedMessage(), e); - } - if (level == null) { - logger.warn("Unable to query D2D parms, ParmID " + id - + " does not map to a level"); + if (level == null) { + logger.warn("Unable to query D2D parms, ParmID " + id + + " does not map to a level"); return new TreeMap(); - } + } SQLQuery modelQuery = s.createSQLQuery(SQL_D2D_GRID_PARM_QUERY); modelQuery.setLong("level_id", level.getId()); DatabaseID dbId = id.getDbId(); - try { - IFPServerConfig config = IFPServerConfigManager - .getServerConfig(dbId.getSiteId()); + try { + IFPServerConfig config = IFPServerConfigManager + .getServerConfig(dbId.getSiteId()); modelQuery.setString(GridInfoConstants.DATASET_ID, config.d2dModelNameMapping(dbId.getModelName())); - } catch (GfeConfigurationException e) { - throw new DataAccessLayerException( - "Error occurred looking up model name mapping", e); - } + } catch (GfeConfigurationException e) { + throw new DataAccessLayerException( + "Error occurred looking up model name mapping", e); + } String abbreviation = null; try { @@ -793,38 +795,38 @@ public class GFEDao extends DefaultPluginDao { } catch (MultipleMappingException e) { statusHandler.handle(Priority.WARN, e.getLocalizedMessage(), e); abbreviation = e.getArbitraryMapping(); - } + } - abbreviation = abbreviation.toLowerCase(); + abbreviation = abbreviation.toLowerCase(); modelQuery.setString("abbrev", abbreviation); modelQuery.setString("hourAbbrev", abbreviation + "%hr"); List results = modelQuery.list(); Integer modelId = null; - if (results.size() == 0) { + if (results.size() == 0) { return new TreeMap(); - } else if (results.size() > 1) { - // hours matched, take hour with least number that matches exact - // param - Pattern p = Pattern.compile("^" + abbreviation + "(\\d+)hr$"); - int lowestHr = -1; + } else if (results.size() > 1) { + // hours matched, take hour with least number that matches exact + // param + Pattern p = Pattern.compile("^" + abbreviation + "(\\d+)hr$"); + int lowestHr = -1; for (Object[] rows : (List) results) { String param = ((String) rows[0]).toLowerCase(); - if (param.equals(abbreviation) && (lowestHr < 0)) { + if (param.equals(abbreviation) && (lowestHr < 0)) { modelId = (Integer) rows[1]; - } else { - Matcher matcher = p.matcher(param); - if (matcher.matches()) { - int hr = Integer.parseInt(matcher.group(1)); - if ((lowestHr < 0) || (hr < lowestHr)) { + } else { + Matcher matcher = p.matcher(param); + if (matcher.matches()) { + int hr = Integer.parseInt(matcher.group(1)); + if ((lowestHr < 0) || (hr < lowestHr)) { modelId = (Integer) rows[1]; - lowestHr = hr; + lowestHr = hr; + } } } } - } - } else { + } else { modelId = (Integer) ((Object[]) results.get(0))[1]; - } + } Query timeQuery = s.createQuery(HQL_D2D_GRID_TIME_QUERY); timeQuery.setInteger("info_id", modelId); @@ -832,7 +834,7 @@ public class GFEDao extends DefaultPluginDao { List timeResults = timeQuery.list(); if (timeResults.isEmpty()) { return new TreeMap(); - } + } SortedMap dataTimes = new TreeMap(); for (Object[] rows : timeResults) { @@ -848,7 +850,7 @@ public class GFEDao extends DefaultPluginDao { try { s = getHibernateTemplate().getSessionFactory().openSession(); - if (id.getParmName().equalsIgnoreCase("wind")) { + if (id.getParmName().equalsIgnoreCase("wind")) { String idString = id.toString(); Matcher idWindMatcher = WIND_PATTERN.matcher(idString); @@ -858,53 +860,53 @@ public class GFEDao extends DefaultPluginDao { List uTimeList = new ArrayList( results.size()); for (DataTime o : results.keySet()) { - uTimeList.add(new TimeRange(o.getValidPeriod().getStart(), - 3600 * 1000)); - } + uTimeList.add(new TimeRange(o.getValidPeriod().getStart(), + 3600 * 1000)); + } ParmID vWindId = new ParmID(idWindMatcher.replaceAll("vW")); results = queryByD2DParmId(vWindId, s); Set vTimeList = new HashSet( results.size(), 1); for (DataTime o : results.keySet()) { - vTimeList.add(new TimeRange(o.getValidPeriod().getStart(), - 3600 * 1000)); - } + vTimeList.add(new TimeRange(o.getValidPeriod().getStart(), + 3600 * 1000)); + } - for (TimeRange tr : uTimeList) { - if (vTimeList.contains(tr)) { - timeList.add(new TimeRange(tr.getStart(), tr.getStart())); - } + for (TimeRange tr : uTimeList) { + if (vTimeList.contains(tr)) { + timeList.add(new TimeRange(tr.getStart(), tr.getStart())); } + } - if (!timeList.isEmpty()) { - return timeList; - } + if (!timeList.isEmpty()) { + return timeList; + } ParmID sWindId = new ParmID(idWindMatcher.replaceAll("ws")); results = queryByD2DParmId(sWindId, s); List sTimeList = new ArrayList( results.size()); for (DataTime o : results.keySet()) { - sTimeList.add(new TimeRange(o.getValidPeriod().getStart(), - 3600 * 1000)); - } + sTimeList.add(new TimeRange(o.getValidPeriod().getStart(), + 3600 * 1000)); + } ParmID dWindId = new ParmID(idWindMatcher.replaceAll("wd")); results = queryByD2DParmId(dWindId, s); Set dTimeList = new HashSet( results.size(), 1); for (DataTime o : results.keySet()) { - dTimeList.add(new TimeRange(o.getValidPeriod().getStart(), - 3600 * 1000)); - } + dTimeList.add(new TimeRange(o.getValidPeriod().getStart(), + 3600 * 1000)); + } - for (TimeRange tr : sTimeList) { - if (dTimeList.contains(tr)) { - timeList.add(new TimeRange(tr.getStart(), tr.getStart())); - } + for (TimeRange tr : sTimeList) { + if (dTimeList.contains(tr)) { + timeList.add(new TimeRange(tr.getStart(), tr.getStart())); } - } else { + } + } else { SortedMap results = queryByD2DParmId(id, s); if (isMos(id)) { for (DataTime o : results.keySet()) { @@ -913,10 +915,10 @@ public class GFEDao extends DefaultPluginDao { } } else { for (DataTime o : results.keySet()) { - timeList.add(o.getValidPeriod()); - } + timeList.add(o.getValidPeriod()); } } + } } finally { if (s != null) { try { diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java index 3a6e179a37..b7347a811b 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java @@ -21,7 +21,6 @@ package com.raytheon.edex.plugin.gfe.server.notify; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -54,10 +53,13 @@ import com.raytheon.uf.common.dataplugin.gfe.server.notify.GridUpdateNotificatio import com.raytheon.uf.common.dataplugin.grid.GridRecord; import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord; import com.raytheon.uf.common.message.WsId; +import com.raytheon.uf.common.parameter.mapping.ParameterMapper; import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.TimeRange; +import com.raytheon.uf.common.util.mapping.MultipleMappingException; import com.raytheon.uf.edex.core.EDEXUtil; /** @@ -71,6 +73,8 @@ import com.raytheon.uf.edex.core.EDEXUtil; * ------------ ---------- ----------- -------------------------- * Aug 12, 2011 dgilling Initial creation * Sep 19, 2012 jdynina DR 15442 fix + * Jan 18, 2013 #1504 randerso Moved D2D to GFE parameter name translation from + * D2DParmIdCache to GfeIngestNotificationFilter * * * @@ -80,7 +84,7 @@ import com.raytheon.uf.edex.core.EDEXUtil; public class GfeIngestNotificationFilter { - private static final transient IUFStatusHandler handler = UFStatus + private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(GfeIngestNotificationFilter.class); private SmartInitQueue smartInitQueue = null; @@ -106,8 +110,7 @@ public class GfeIngestNotificationFilter { } } - public void filterGridRecords(List gridRecords, - Date arrivalTime) + public void filterGridRecords(List gridRecords, Date arrivalTime) throws Exception { StringBuilder initNameBuilder = new StringBuilder(120); @@ -126,7 +129,8 @@ public class GfeIngestNotificationFilter { try { config = IFPServerConfigManager.getServerConfig(site); } catch (GfeConfigurationException e) { - handler.error("Unable to retrieve site config for " + site, e); + statusHandler.error("Unable to retrieve site config for " + + site, e); continue; } for (GridRecord grid : gridRecords) { @@ -152,24 +156,33 @@ public class GfeIngestNotificationFilter { } String abbrev = grid.getParameter().getAbbreviation(); - String level = GridTranslator.getShortLevelName( -grid + String gfeParmName = null; + try { + gfeParmName = ParameterMapper.getInstance() + .lookupAlias(abbrev, "gfeParamName"); + } catch (MultipleMappingException e) { + statusHandler.handle(Priority.WARN, + e.getLocalizedMessage(), e); + gfeParmName = e.getArbitraryMapping(); + } + + String level = GridTranslator.getShortLevelName(grid .getLevel().getMasterLevel().getName(), grid .getLevel().getLevelonevalue(), grid.getLevel() .getLeveltwovalue()); - ParmID parmID = new ParmID(abbrev, dbId, level); + ParmID parmID = new ParmID(gfeParmName, dbId, level); - if (!gridInv.containsKey(parmID)) { - gridInv.put(parmID, new ArrayList()); + List trs = gridInv.get(parmID); + if (trs == null) { + trs = new ArrayList(); + gridInv.put(parmID, trs); } TimeRange validPeriod = grid.getDataTime().getValidPeriod(); if (validPeriod.getDuration() > 0) { - gridInv.get(parmID).add(validPeriod); + trs.add(validPeriod); } else { - gridInv.get(parmID).add( - new TimeRange(grid.getDataTime() - .getValidPeriod().getStart(), - 3600 * 1000)); + trs.add(new TimeRange(grid.getDataTime() + .getValidPeriod().getStart(), 3600 * 1000)); } List siteInitModules = config.initModels(gfeModel); @@ -201,31 +214,29 @@ grid // DR 15442 - move last for loop out of the for loop at line 110 for (ParmID parmId : gridInv.keySet()) { - Map> hist = new HashMap>(); try { List trs = gridInv.get(parmId); - Collections.sort(trs); for (TimeRange time : trs) { List histList = new ArrayList(); histList.add(new GridDataHistory( - GridDataHistory.OriginType.INITIALIZED, - parmId, time, null, (WsId) null)); + GridDataHistory.OriginType.INITIALIZED, parmId, + time, null, (WsId) null)); + Map> hist = new HashMap>(); hist.put(time, histList); + guns.add(new GridUpdateNotification(parmId, time, hist, + null, parmId.getDbId().getSiteId())); } - guns.add(new GridUpdateNotification(parmId, - new TimeRange(trs.get(0).getStart(), trs.get( - trs.size() - 1).getEnd()), hist, null, - parmId.getDbId().getSiteId())); } catch (Exception e) { - handler.error("Unable to retrieve grid history for " + statusHandler.error("Unable to retrieve grid history for " + parmId.toString(), e); } } - + try { sendNotifications(guns); } catch (Exception e) { - handler.error("Unable to send grib ingest notifications", e); + statusHandler.error("Unable to send grib ingest notifications", + e); } smartInitQueue.addInits(inits.values()); @@ -233,8 +244,7 @@ grid } public void filterSatelliteRecords(List records, - Date arrivalTime) - throws Exception { + Date arrivalTime) throws Exception { StringBuilder initNameBuilder = new StringBuilder(120); Set activeSites = GFESiteActivation.getInstance() @@ -249,7 +259,8 @@ grid try { config = IFPServerConfigManager.getServerConfig(site); } catch (GfeConfigurationException e) { - handler.error("Error retrieiving site config for " + site, e); + statusHandler.error( + "Error retrieiving site config for " + site, e); continue; } @@ -298,8 +309,8 @@ grid try { sendNotifications(guns); } catch (Exception e) { - handler.error("Unable to send satellite ingest notifications", - e); + statusHandler.error( + "Unable to send satellite ingest notifications", e); } smartInitQueue.addInits(inits.values()); diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/GribDecoder.py b/edexOsgi/com.raytheon.edex.plugin.grib/GribDecoder.py index 47d00f2970..9da78b1cab 100644 --- a/edexOsgi/com.raytheon.edex.plugin.grib/GribDecoder.py +++ b/edexOsgi/com.raytheon.edex.plugin.grib/GribDecoder.py @@ -593,19 +593,19 @@ class GribDecoder(): # Special case handling for specific PDS Templates if pdsTemplateNumber == 1 or pdsTemplateNumber == 11: - typeEnsemble = Integer(pdsTemplate[15]) - perturbationNumber = Integer(pdsTemplate[16]) + typeEnsemble = Integer(pdsTemplate[15]).intValue() + perturbationNumber = Integer(pdsTemplate[16]).intValue() pdsFields['numForecasts'] = Integer(pdsTemplate[17]) if(typeEnsemble == 0): - pdsFields['ensembleId'] = "ctlh" + perturbationNumber; + pdsFields['ensembleId'] = "ctlh" + str(perturbationNumber); elif(typeEnsemble == 1): - pdsFields['ensembleId'] = "ctll" + perturbationNumber; + pdsFields['ensembleId'] = "ctll" + str(perturbationNumber); elif(typeEnsemble == 2): - pdsFields['ensembleId'] = "n" + perturbationNumber; + pdsFields['ensembleId'] = "n" + str(perturbationNumber); elif(typeEnsemble == 3): - pdsFields['ensembleId'] = "p" + perturbationNumber; + pdsFields['ensembleId'] = "p" + str(perturbationNumber); else: - pdsFields['ensembleId'] = typeEnsemble + "." + perturbationNumber; + pdsFields['ensembleId'] = str(typeEnsemble) + "." + str(perturbationNumber); if pdsTemplateNumber == 11: endTime = GregorianCalendar(pdsTemplate[18], pdsTemplate[19] - 1, pdsTemplate[20], pdsTemplate[21], pdsTemplate[22], pdsTemplate[23]) diff --git a/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/RadarDecoder.java b/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/RadarDecoder.java index 55dcefe7b6..c7f7bba8f4 100644 --- a/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/RadarDecoder.java +++ b/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/RadarDecoder.java @@ -22,6 +22,7 @@ package com.raytheon.edex.plugin.radar; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.List; @@ -95,6 +96,30 @@ public class RadarDecoder extends AbstractDecoder { private static final IUFStatusHandler theHandler = UFStatus .getHandler(RadarDecoder.class); + // radar server sends messages from edex to cave, handle that here + private final String EDEX = "EDEX"; + + /* + * Constants having to do with certain products + */ + + private final List LEVEL_TWO_IDENTS = new ArrayList( + Arrays.asList("ARCH", "AR2V")); + + private final String NOUS = "NOUS"; + + private final int USER_ALERT_MESSAGE = 73; + + private final int FREE_TEXT_MESSAGE = 75; + + private final int USER_SELECT_ACCUM = 173; + + private final int CLUTTER_FILTER_CONTROL = 34; + + /* + * End constants + */ + private String traceId = ""; private RadarInfoDict infoDict; @@ -103,9 +128,6 @@ public class RadarDecoder extends AbstractDecoder { private final String RADAR = "RADAR"; - // radar server sends messages from edex to cave, handle that here - private final String EDEX = "EDEX"; - public RadarDecoder() throws DecoderException { String dir = ""; @@ -146,11 +168,11 @@ public class RadarDecoder extends AbstractDecoder { String arch = new String(messageData, 0, 4); try { // for level2 data, this does not happen very often - if ("ARCH".equals(arch) || "AR2V".equals(arch)) { + if (LEVEL_TWO_IDENTS.contains(arch)) { decodeLevelTwoData(messageData, recordList); } // for free text messages, which come in with the following wmo - else if ("NOUS".equals(arch)) { + else if (NOUS.equals(arch)) { decodeFreeTextMessage(messageData, headers); } else { if (headers.get("header") != null) { @@ -208,24 +230,19 @@ public class RadarDecoder extends AbstractDecoder { // -- some product specific decode functionality -- // the general status message product - if (l3Radar.getMessageCode() == 2) { + if (l3Radar.getMessageCode() == l3Radar.GSM_MESSAGE) { record.setGsmMessage(l3Radar.getGsmBlock().getMessage()); record.setPrimaryElevationAngle(0.0); record.setTrueElevationAngle(0.0f); handleRadarStatus(record); } // the product request response product - else if (l3Radar.getMessageCode() == 3) { + else if (l3Radar.getMessageCode() == l3Radar.PRODUCT_REQUEST_RESPONSE_MESSAGE) { // do nothing with this, it will get excessive otherwise! - // EDEXUtil.sendMessageAlertViz(Priority.VERBOSE, - // RadarConstants.PLUGIN_ID, EDEX, RADAR, - // record.getIcao() - // + ": Response Request Message Received", - // l3Radar.getRequestResponseMessage(), null); return new PluginDataObject[0]; } // the user alert message product - else if (l3Radar.getMessageCode() == 73) { + else if (l3Radar.getMessageCode() == USER_ALERT_MESSAGE) { EDEXUtil.sendMessageAlertViz(Priority.VERBOSE, RadarConstants.PLUGIN_ID, EDEX, RADAR, record.getIcao() + ": User Alert Message Received", @@ -233,21 +250,19 @@ public class RadarDecoder extends AbstractDecoder { return new PluginDataObject[0]; } // handle the other case for free text message - else if (l3Radar.getMessageCode() == 75) { + else if (l3Radar.getMessageCode() == FREE_TEXT_MESSAGE) { // product already stored to the text database, so just send // to alertviz - EDEXUtil.sendMessageAlertViz( - Priority.SIGNIFICANT, - RadarConstants.PLUGIN_ID, - EDEX, - RADAR, + String formattedMsg = l3Radar.getTabularBlock().toString() + .replace("Page 1\n\t", ""); + EDEXUtil.sendMessageAlertViz(Priority.SIGNIFICANT, + RadarConstants.PLUGIN_ID, EDEX, RADAR, record.getIcao() + ": Free Text Message Received", - l3Radar.getTabularBlock().toString() - .replace("Page 1\n\t", ""), null); + formattedMsg, null); return new PluginDataObject[0]; } // the alert adaptations parameters product - else if (l3Radar.getMessageCode() == 6) { + else if (l3Radar.getMessageCode() == l3Radar.ALERT_ADAPTATION_PARAMETERS) { record.setAapMessage(l3Radar.getAapMessage()); record.setPrimaryElevationAngle(0.0); record.setTrueElevationAngle(0.0f); @@ -261,7 +276,7 @@ public class RadarDecoder extends AbstractDecoder { l3Radar.getAapMessage().toString(), null); } // the alert message product - else if (l3Radar.getMessageCode() == 9) { + else if (l3Radar.getMessageCode() == l3Radar.ALERT_MESSAGE) { record.setPrimaryElevationAngle(0.0); record.setTrueElevationAngle(0.0f); AlertMessage msg = l3Radar.getAlertMessage(); @@ -291,6 +306,8 @@ public class RadarDecoder extends AbstractDecoder { record.setOperationalMode(l3Radar.getOperationalMode()); record.setElevationNumber(l3Radar.getElevationNumber()); + // some products don't have real elevation angles, 0 is a + // default value if (record.getElevationNumber() == 0) { record.setTrueElevationAngle(0f); } else { @@ -320,13 +337,13 @@ public class RadarDecoder extends AbstractDecoder { } // code specific for clutter filter control - if (record.getProductCode() == 34) { + if (record.getProductCode() == CLUTTER_FILTER_CONTROL) { int segment = ((int) (Math.log(l3Radar .getProductDependentValue(0)) / Math.log(2))); record.setLayer((double) segment); } // code specific for user select accum - else if (record.getProductCode() == 173) { + else if (record.getProductCode() == USER_SELECT_ACCUM) { int layer = 0; // Default to zero int timeSpan = l3Radar.getProductDependentValue(1); @@ -491,7 +508,8 @@ public class RadarDecoder extends AbstractDecoder { String[] splits = temp.split(" "); AFOSProductId afos = new AFOSProductId( - RadarTextProductUtil.createAfosId(75, splits[1].substring(1))); + RadarTextProductUtil.createAfosId(FREE_TEXT_MESSAGE, + splits[1].substring(1))); // store the product to the text database Calendar cal = (TimeTools.allowArchive() ? header.getHeaderDate() @@ -510,7 +528,9 @@ public class RadarDecoder extends AbstractDecoder { record.setPluginName("radar"); record.constructDataURI(); record.setInsertTime(TimeTools.getSystemCalendar()); - if (record.getProductCode() == 2) { + // for GSM, we want all the messages as they have the possibility of + // being different + if (record.getProductCode() == Level3BaseRadar.GSM_MESSAGE) { record.setOverwriteAllowed(true); } else { record.setOverwriteAllowed(false); @@ -669,7 +689,8 @@ public class RadarDecoder extends AbstractDecoder { } } catch (Exception e) { - e.printStackTrace(); + theHandler.handle(Priority.ERROR, + "Unable to query for the radar station", e); } return station; diff --git a/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/level3/Level3BaseRadar.java b/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/level3/Level3BaseRadar.java index 74311c15fa..96234440ff 100644 --- a/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/level3/Level3BaseRadar.java +++ b/edexOsgi/com.raytheon.edex.plugin.radar/src/com/raytheon/edex/plugin/radar/level3/Level3BaseRadar.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.io.InputStream; import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -178,6 +179,21 @@ public class Level3BaseRadar { private RadarInfoDict dict = null; + private final List SPECIAL_PRODS = new ArrayList( + Arrays.asList(73, 62, 75, 77, 82)); + + public static final int GSM_MESSAGE = 2; + + public final int PRODUCT_REQUEST_RESPONSE_MESSAGE = 3; + + public final int ALERT_ADAPTATION_PARAMETERS = 6; + + public final int PRODUCT_LIST = 8; + + public final int RADAR_CODED_MESSAGE = 74; + + public final int ALERT_MESSAGE = 9; + /** * This baseradar constructor accepts a radar file contained within a * java.io.File object. @@ -251,16 +267,16 @@ public class Level3BaseRadar { this.parseRadarHeader(); // Handle the message contents - if (this.theMessageCode == 6) { + if (this.theMessageCode == ALERT_ADAPTATION_PARAMETERS) { // Alert Adaptation Params this.parseAAP(); - } else if (this.theMessageCode == 3) { + } else if (this.theMessageCode == PRODUCT_REQUEST_RESPONSE_MESSAGE) { this.parseRequestResponse(); - } else if (this.theMessageCode == 8) { + } else if (this.theMessageCode == PRODUCT_LIST) { this.parseProductList(headers); - } else if (this.theMessageCode == 2) { + } else if (this.theMessageCode == GSM_MESSAGE) { this.parseGeneralStatusMessage(); - } else if (this.theMessageCode == 9) { + } else if (this.theMessageCode == ALERT_MESSAGE) { this.parseAlertMessage(headers); } else { this.parseRadarMessage(headers); @@ -593,8 +609,13 @@ public class Level3BaseRadar { byte[] buf = new byte[lineLen]; theRadarData.readFully(buf); String temp = new String(buf); + // PSM is found in all products that have useful Site Adaptation + // Parameters. For this reason, we are dropping every other set of + // Site Adaptation Parameters. if (temp.contains("PSM")) { temp = temp.substring(temp.indexOf("PSM")); + } else { + temp = ""; } return temp; } else { @@ -795,15 +816,13 @@ public class Level3BaseRadar { } } - if (this.theProductCode == 73 || this.theProductCode == 62 - || this.theProductCode == 75 || this.theProductCode == 77 - || this.theProductCode == 82) { + if (SPECIAL_PRODS.contains(this.theProductCode)) { // The first offset will be to the tabular block tabularBlock = readStandaloneTabular(symbologyBlockOffset); // The second offset will be to a symbology block with no header symbologyBlock = readPseudoSymbologyBlock(graphicBlockOffset); // tabularBlock.getPages().toString(); - } else if (this.theProductCode == 74) { + } else if (this.theProductCode == RADAR_CODED_MESSAGE) { tabularBlock = readRadarCodedMessage(symbologyBlockOffset); } else { symbologyBlock = readSymbologyBlock(symbologyBlockOffset); diff --git a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/AbstractPrivilegedLocalizationRequestHandler.java b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/AbstractPrivilegedLocalizationRequestHandler.java index e5709ca09a..d8cadca0bb 100644 --- a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/AbstractPrivilegedLocalizationRequestHandler.java +++ b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/AbstractPrivilegedLocalizationRequestHandler.java @@ -19,13 +19,16 @@ **/ package com.raytheon.edex.services; -import java.io.File; +import java.util.HashSet; +import java.util.Set; import com.raytheon.uf.common.auth.exception.AuthorizationException; import com.raytheon.uf.common.auth.req.AbstractPrivilegedRequest; import com.raytheon.uf.common.auth.user.IUser; +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.uf.edex.auth.AuthManager; import com.raytheon.uf.edex.auth.AuthManagerFactory; import com.raytheon.uf.edex.auth.req.AbstractPrivilegedRequestHandler; @@ -51,87 +54,85 @@ import com.raytheon.uf.edex.auth.roles.IRoleStorage; */ public abstract class AbstractPrivilegedLocalizationRequestHandler extends AbstractPrivilegedRequestHandler { - + + private static final String PATH_SEPARATOR = IPathManager.SEPARATOR; + + private static final String SEPARATOR = "."; + + private static final String ROLE_PREFIX = "com.raytheon.localization"; + private static final String APPLICATION = "Localization"; protected AuthorizationResponse getAuthorizationResponse(IUser user, - LocalizationContext context, LocalizationLevel level, - String fileName, String myContextName) + LocalizationContext context, String fileName, String myContextName) throws AuthorizationException { String contextName = context.getContextName(); - + LocalizationLevel level = context.getLocalizationLevel(); + LocalizationType type = context.getLocalizationType(); + boolean contextsMatch = (myContextName != null && myContextName + .equals(contextName)); if (level.isSystemLevel()) { return new AuthorizationResponse(false, "Modification to system level configuration is prohibited."); - } else if (myContextName != null - && myContextName.equals(contextName) - && (context.getLocalizationLevel() == LocalizationLevel.USER || context - .getLocalizationLevel() == LocalizationLevel.WORKSTATION)) { - // If context names match and we are user or workstation file - // request, that is ok + } else if (level == LocalizationLevel.USER && contextsMatch) { + // Don't prevent users from modifying own files return new AuthorizationResponse(true); } AuthManager manager = AuthManagerFactory.getInstance().getManager(); IRoleStorage roleStorage = manager.getRoleStorage(); - String roleId = ""; + String[] permissions = roleStorage + .getAllDefinedPermissions(APPLICATION); + Set definedPermissions = new HashSet(); + for (String permission : permissions) { + definedPermissions.add(permission.toLowerCase()); + } + String absoluteRoleId = buildRoleId(level, type, contextName, fileName); // First round check com.raytheon.localization.level // Second round check com.raytheon.localization.level.name for (int i = 0; i < 2; ++i) { - roleId = "com.raytheon.localization." - + context.getLocalizationLevel().name() - + "/" + context.getLocalizationType().name(); - if (i > 0) { - if (contextName != null) { - roleId += "." + contextName; - } else { - // We already checked this case - break; - } - } - + String contextNameToUse = i > 0 ? contextName : null; + String roleId = buildRoleId(level, type, contextNameToUse, fileName); + // check most specific to least specific // com.raytheon.localization..(.)/type/path/name/ - int minIndex = roleId.length(); - roleId += File.separator + fileName; - int index = roleId.length(); - - while (index > minIndex) { - roleId = roleId.substring(0, index); - - if (roleStorage.isAuthorized(roleId, user.uniqueId().toString(), APPLICATION)) { + int minLength = roleId.length() - fileName.length() - 1; + do { + if (roleStorage.isAuthorized(roleId, + user.uniqueId().toString(), APPLICATION)) { return new AuthorizationResponse(true); + } else if (definedPermissions.contains(roleId.toLowerCase())) { + // User not authorized and this roleId is explicitly defined + return notAuthorized(user, absoluteRoleId); } - index = roleId.lastIndexOf(File.separator, index - 1); - } - - roleId = "com.raytheon.localization." - + context.getLocalizationLevel().name(); - if (i > 0) { - if (contextName != null) { - roleId += "." + contextName; - } else { - // We already checked this case - break; - } - } - - // com.raytheon.localization..() - if (roleStorage.isAuthorized(roleId, user.uniqueId().toString(), APPLICATION)) { - return new AuthorizationResponse(true); - } - - // com.raytheon.localization..(.)/type - roleId += "/" + context.getLocalizationType().name(); - - if (roleStorage.isAuthorized(roleId, user.uniqueId().toString(), APPLICATION)) { - return new AuthorizationResponse(true); - } - + roleId = roleId.substring(0, + roleId.lastIndexOf(PATH_SEPARATOR, roleId.length())); + } while (roleId.length() >= minLength); } - + + if (level == LocalizationLevel.WORKSTATION && contextsMatch) { + // If no rule found and user is attempting to modify workstation + // they are using, default to allow + return new AuthorizationResponse(true); + } + + return notAuthorized(user, absoluteRoleId); + } + + private String buildRoleId(LocalizationLevel level, LocalizationType type, + String contextName, String fileName) { + String roleId = ROLE_PREFIX + SEPARATOR + level; + if (contextName != null) { + roleId += SEPARATOR + contextName; + } + roleId += PATH_SEPARATOR + type; + roleId += PATH_SEPARATOR + fileName; + return roleId; + } + + private AuthorizationResponse notAuthorized(IUser user, String roleId) { return new AuthorizationResponse(false, "User, " + user.uniqueId() + ", is not authorized to perform request needing role: " + roleId); diff --git a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/LocalizationStreamHandler.java b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/LocalizationStreamHandler.java index 08d8319ffa..0182e96717 100644 --- a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/LocalizationStreamHandler.java +++ b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/LocalizationStreamHandler.java @@ -294,9 +294,8 @@ public class LocalizationStreamHandler return new AuthorizationResponse(true); } else if (request instanceof LocalizationStreamPutRequest) { LocalizationContext context = request.getContext(); - LocalizationLevel level = context.getLocalizationLevel(); String fileName = request.getFileName(); - return getAuthorizationResponse(user, context, level, fileName, + return getAuthorizationResponse(user, context, fileName, request.getMyContextName()); } return new AuthorizationResponse(true); diff --git a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/PrivilegedUtilityHandler.java b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/PrivilegedUtilityHandler.java index a4b9df6d99..13fedf2ea9 100644 --- a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/PrivilegedUtilityHandler.java +++ b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/PrivilegedUtilityHandler.java @@ -6,7 +6,6 @@ import java.util.List; import com.raytheon.uf.common.auth.exception.AuthorizationException; import com.raytheon.uf.common.auth.user.IUser; import com.raytheon.uf.common.localization.LocalizationContext; -import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; import com.raytheon.uf.common.localization.msgs.AbstractPrivilegedUtilityCommand; import com.raytheon.uf.common.localization.msgs.AbstractUtilityResponse; import com.raytheon.uf.common.localization.msgs.DeleteUtilityCommand; @@ -73,10 +72,9 @@ public class PrivilegedUtilityHandler AbstractPrivilegedUtilityCommand[] commands = request.getCommands(); for (AbstractPrivilegedUtilityCommand abstractUtilityCommand : commands) { LocalizationContext context = abstractUtilityCommand.getContext(); - LocalizationLevel level = context.getLocalizationLevel(); String filename = abstractUtilityCommand.getFilename(); AuthorizationResponse resp = getAuthorizationResponse(user, - context, level, filename, + context, filename, abstractUtilityCommand.getMyContextName()); if (resp.isAuthorized() == false) { // If we are not authorized for any of the commands, break early diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/src/com/raytheon/uf/common/datadelivery/bandwidth/data/BandwidthGraphData.java b/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/src/com/raytheon/uf/common/datadelivery/bandwidth/data/BandwidthGraphData.java index 0c4be4b3cd..7d045becea 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/src/com/raytheon/uf/common/datadelivery/bandwidth/data/BandwidthGraphData.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/src/com/raytheon/uf/common/datadelivery/bandwidth/data/BandwidthGraphData.java @@ -27,23 +27,25 @@ import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** * Response object for the GraphDataRequest. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Nov 25, 2012    1269    lvenable    Initial creation.
  * Dec 06, 2012    1397    djohnson    Add dynamic serialize class annotation.
- *
+ * Jan 25, 2013   1528     djohnson    Subscription priority is now an enum.
+ * 
  * 
- * + * * @author lvenable * @version 1.0 */ @@ -55,7 +57,7 @@ public class BandwidthGraphData { /** Subscription Name -> Subscription Priority */ @DynamicSerializeElement - private Map priorityMap; + private Map priorityMap; /** Bin duration in minutes */ @DynamicSerializeElement @@ -81,7 +83,7 @@ public class BandwidthGraphData { public BandwidthGraphData(int binTimeMins) { this.binTimeInMins = binTimeMins; dataMap = new HashMap>(); - priorityMap = new HashMap(); + priorityMap = new HashMap(); } /** @@ -102,7 +104,7 @@ public class BandwidthGraphData { /** * @return the priorityMap */ - public Map getPriorityMap() { + public Map getPriorityMap() { return priorityMap; } @@ -110,7 +112,7 @@ public class BandwidthGraphData { * @param priorityMap * the priorityMap to set */ - public void setPriorityMap(Map priorityMap) { + public void setPriorityMap(Map priorityMap) { this.priorityMap = priorityMap; } @@ -145,7 +147,8 @@ public class BandwidthGraphData { * @param priority * @param dataArray */ - public void addGraphDataArray(String subscriptionName, int priority, + public void addGraphDataArray(String subscriptionName, + SubscriptionPriority priority, List dataArray) { dataMap.put(subscriptionName, dataArray); priorityMap.put(subscriptionName, priority); @@ -206,14 +209,15 @@ public class BandwidthGraphData { * The subscription name. * @return The priority number. */ - public int getPriority(String subscriptionName) { + public SubscriptionPriority getPriority(String subscriptionName) { if (priorityMap.containsKey(subscriptionName)) { return priorityMap.get(subscriptionName); } - // This should never occur. A low priority number is being return rather - // than a null. - return 99; + // This should never occur. + throw new IllegalArgumentException( + "Unable to find a priority for subscription [" + + subscriptionName + "]"); } /** diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/utility/common_static/base/datadelivery/systemManagement/rules/latencyRules.xml b/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/utility/common_static/base/datadelivery/systemManagement/rules/latencyRules.xml index ab09f88dfb..f686a0eda8 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/utility/common_static/base/datadelivery/systemManagement/rules/latencyRules.xml +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/utility/common_static/base/datadelivery/systemManagement/rules/latencyRules.xml @@ -1,19 +1,19 @@ - + Dataset Frequency Hourly-Products <= Hrs 1 40 - - + + Dataset Frequency MultiHour-Products > Hrs 1 115 - + diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rtofsLevelLookup.xml b/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/utility/common_static/base/datadelivery/systemManagement/rules/priorityRules.xml similarity index 52% rename from edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rtofsLevelLookup.xml rename to edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/utility/common_static/base/datadelivery/systemManagement/rules/priorityRules.xml index 1cb435de22..36fe07252c 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rtofsLevelLookup.xml +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.bandwidth/utility/common_static/base/datadelivery/systemManagement/rules/priorityRules.xml @@ -1,4 +1,4 @@ - - 1.0 - \ No newline at end of file + + + diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.datadelivery.event/META-INF/MANIFEST.MF index 772a6e8dbc..2ffd2f8400 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.event/META-INF/MANIFEST.MF @@ -17,4 +17,5 @@ Require-Bundle: javax.persistence;bundle-version="1.0.0", com.raytheon.uf.common.event;bundle-version="1.0.0", com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174", com.raytheon.uf.common.time;bundle-version="1.12.1174", - com.raytheon.uf.common.stats;bundle-version="1.0.0" + com.raytheon.uf.common.stats;bundle-version="1.0.0", + com.raytheon.uf.common.registry.ebxml;bundle-version="1.0.0" diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/META-INF/MANIFEST.MF index e5cd0a4626..9a73f1811e 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/META-INF/MANIFEST.MF @@ -23,7 +23,8 @@ Require-Bundle: com.raytheon.uf.common.registry.schemas.ebxml;bundle-version="1. com.raytheon.uf.common.gridcoverage;bundle-version="1.0.0", com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174", com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", - javax.measure;bundle-version="1.0.0" + javax.measure;bundle-version="1.0.0", + com.raytheon.uf.common.datadelivery.request;bundle-version="1.0.0" Export-Package: com.raytheon.uf.common.datadelivery.registry, com.raytheon.uf.common.datadelivery.registry.ebxml, com.raytheon.uf.common.datadelivery.registry.handlers diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/DataLevelType.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/DataLevelType.java index 000eb39f8e..24d3ed4b42 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/DataLevelType.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/DataLevelType.java @@ -31,6 +31,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Code clean up. * Set 06, 2012 1121 mpduff Added a unique key. * Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects. + * Jan 24, 2013 1527 dhladky Changed 0DEG to FRZ * * * @@ -110,7 +111,7 @@ public class DataLevelType implements ISerializableObject, Serializable { "Cloud Level", 110), SIGL("sigma", "Sigma Level", 111), PVL( "pv", "PV Level", 111), CTL("top", "Top Level", 112), MSL( "mean", "Mean Sea Level", 113), EA("entire", - "Entire Atmosphere (As Single Layer)", 114), ODEG("0c", + "Entire Atmosphere (As Single Layer)", 114), FRZ("0c", "0c isotherm", 115), LCY("low", "Low Cloud Bottom Level", 116), MCY( "middle", "Middle Cloud Level", 117), HCY("high", "High Cloud Level", 118), PBL("planetary", @@ -175,11 +176,8 @@ public class DataLevelType implements ISerializableObject, Serializable { break; } } - - // special case since enums can't start with integers - if (rval == LevelType.ODEG) { - return "0DEG"; - } else if (rval == LevelType.U || rval == LevelType.V) { + + if (rval == LevelType.U || rval == LevelType.V) { return LevelType.MAXW.toString(); } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Ensemble.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Ensemble.java index d53cd8625a..3d9047cea0 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Ensemble.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Ensemble.java @@ -1,5 +1,9 @@ package com.raytheon.uf.common.datadelivery.registry; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; @@ -30,67 +34,161 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @DynamicSerialize public class Ensemble implements ISerializableObject { + /** + * names of the various ensemble members + */ + @DynamicSerializeElement + @XmlAttribute + private List members; + + /** + * which members to request. + */ + @DynamicSerializeElement + @XmlAttribute + private List selectedMembers; + public Ensemble() { } - /** - * ensemble models set this - */ - @DynamicSerializeElement - @XmlAttribute - private String name; + public Ensemble(Ensemble other) { + if (other.members != null) { + members = new ArrayList(other.members); + } + if (other.selectedMembers != null) { + selectedMembers = new ArrayList(other.selectedMembers); + } + } + + public List getMembers() { + return members; + } + + public void setMembers(List members) { + this.members = members; + } + + public List getSelectedMembers() { + return selectedMembers; + } + + public void setSelectedMembers(List selectedMembers) { + this.selectedMembers = selectedMembers; + } + + public int getMemberCount() { + if (members == null) { + // if no members are defined then assume a single unnamed member. + return 1; + } else { + return members.size(); + } + } + + public int getSelectedMemberCount() { + if (members == null) { + // if no members are defined then assume a single unnamed member + // which is automatically selected + return 1; + } else if (selectedMembers == null) { + return 0; + } else { + return selectedMembers.size(); + } + } + + public boolean hasSelection() { + return selectedMembers != null && !selectedMembers.isEmpty(); + } /** - * ensemble models set this + * + * Get the range of indices of the selected members, inclusively. This + * method should usually be used after a split operation to guarantee that + * selected ensembles are consecutive + * + * @return a int[2] representing the start and end indices of the ensemble + * members + * @throws IllegalStateException + * if the selected member are non consecutive. */ - @DynamicSerializeElement - @XmlAttribute - private String length; + public int[] getSelectedRange() { + int[] result = new int[2]; + int[] indexes = getSortedIndexes(); + if (indexes == null) { + return result; + } + result[0] = indexes[0]; + result[1] = result[0] - 1; + for (int index : indexes) { + result[1] += 1; + if (result[1] != index) { + throw new IllegalStateException( + "Cannot get selected range for nonconsecutive ensemble members\nMembers " + + members + "\nSelected" + selectedMembers); + } + } + return result; + } /** - * ensemble models set this + * Split this ensemble into multiple Ensembles each with consecutive + * members. Used in cases where multiple ensembles can be requested at once + * if they are consecutive. + * + * @param maxEnsembles + * The mazximum number of consecutive members in any Ensemble + * @return */ - @DynamicSerializeElement - @XmlAttribute - private String init; - - /** - * ensemble models set this - */ - @DynamicSerializeElement - @XmlAttribute - private Integer size; - - public void setName(String name) { - this.name = name; + public List split(int maxEnsembles) { + int[] indexes = getSortedIndexes(); + if (indexes == null) { + return Arrays.asList(new Ensemble(this)); + } + List result = new ArrayList(); + List selected = new ArrayList(selectedMembers.size()); + int start = indexes[0]; + int end = start - 1; + for (int index : indexes) { + end += 1; + if (index != end || (end - start) >= maxEnsembles) { + // Either we have run out of consecutive indexes or we have the + // max consecutive. so split off and start the next one. + Ensemble e = new Ensemble(this); + e.setSelectedMembers(new ArrayList(selected)); + selected.clear(); + result.add(e); + start = index; + end = start; + } + selected.add(members.get(index)); + } + Ensemble e = new Ensemble(this); + e.setSelectedMembers(selected); + result.add(e); + return result; } - public String getName() { - return name; + private int[] getSortedIndexes() { + if (!hasSelection()) { + return null; + } + int[] indexes = new int[selectedMembers.size()]; + int c = 0; + for (String selected : selectedMembers) { + int index = members.indexOf(selected); + if (index >= 0) { + indexes[c++] = index; + } + } + if (c == 0) { + return null; + } else if (c < indexes.length) { + indexes = Arrays.copyOf(indexes, c); + } + Arrays.sort(indexes); + return indexes; } - public void setSize(Integer size) { - this.size = size; - } - - public Integer getSize() { - return size; - } - - public void setLength(String length) { - this.length = length; - } - - public String getLength() { - return length; - } - - public void setInit(String init) { - this.init = init; - } - - public String getInit() { - return init; - } } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSet.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSet.java index 69dc1aaba9..39c50ecf39 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSet.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSet.java @@ -20,6 +20,7 @@ package com.raytheon.uf.common.datadelivery.registry; import java.util.HashSet; +import java.util.List; import java.util.Set; import javax.xml.bind.annotation.XmlAccessType; @@ -59,6 +60,10 @@ public abstract class GriddedDataSet extends DataSet { @DynamicSerializeElement protected Set forecastHours = new HashSet(); + @DynamicSerializeElement + @XmlElement + private Ensemble ensemble; + /** * @return the cycles */ @@ -89,6 +94,14 @@ public abstract class GriddedDataSet extends DataSet { this.forecastHours = forecastHours; } + public Ensemble getEnsemble() { + return ensemble; + } + + public void setEnsemble(Ensemble ensemble) { + this.ensemble = ensemble; + } + /** * {@inheritDoc} */ @@ -100,6 +113,15 @@ public abstract class GriddedDataSet extends DataSet { GriddedDataSet other = (GriddedDataSet) toCombine; this.getCycles().addAll(other.getCycles()); this.getForecastHours().addAll(other.getForecastHours()); + if (this.getEnsemble() != null) { + List mine = this.getEnsemble().getSelectedMembers(); + List theirs = other.getEnsemble().getSelectedMembers(); + if (mine == null) { + ensemble.setSelectedMembers(theirs); + } else if (theirs != null) { + mine.addAll(theirs); + } + } } } } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSetMetaData.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSetMetaData.java index bd620a29c4..70466a535c 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSetMetaData.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GriddedDataSetMetaData.java @@ -6,7 +6,6 @@ import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @@ -60,13 +59,6 @@ public abstract class GriddedDataSetMetaData extends @SlotAttribute(CYCLE_SLOT) private int cycle = NO_CYCLE; - /** - * ensemble models set this - */ - @DynamicSerializeElement - @XmlElement - private Ensemble ensemble; - public void setLevelTypes(Map levelTypes) { this.levelTypes = levelTypes; } @@ -92,11 +84,4 @@ public abstract class GriddedDataSetMetaData extends return cycle; } - public void setEnsemble(Ensemble ensemble) { - this.ensemble = ensemble; - } - - public Ensemble getEnsemble() { - return ensemble; - } } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GroupDefinitionServiceRequest.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GroupDefinitionServiceRequest.java new file mode 100644 index 0000000000..1bb6016c1e --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/GroupDefinitionServiceRequest.java @@ -0,0 +1,85 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.datadelivery.registry; + +import com.raytheon.uf.common.auth.req.AbstractPrivilegedRequest; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Service request for {@link GroupDefinition}s. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2013 1441       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@DynamicSerialize +public class GroupDefinitionServiceRequest extends AbstractPrivilegedRequest { + + public static enum Type { + DELETE; + } + + @DynamicSerializeElement + private GroupDefinition group; + + @DynamicSerializeElement + private Type type; + + /** + * @return the type + */ + public Type getType() { + return type; + } + + /** + * @param type + * the type to set + */ + public void setType(Type type) { + this.type = type; + } + + /** + * @return the group + */ + public GroupDefinition getGroup() { + return group; + } + + /** + * @param group + * the group to set + */ + public void setGroup(GroupDefinition group) { + this.group = group; + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Levels.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Levels.java index 4407a8b0f2..a8eec4aa03 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Levels.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Levels.java @@ -25,6 +25,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Feb 08, 2011 191 dhladky Initial creation * Jul 24, 2012 955 djohnson Use List instead of ArrayList. * Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects. + * Jan 28, 2013 1530 djohnson Never return null for selected level indices. * * * @author dhladky @@ -67,7 +68,7 @@ public class Levels implements ISerializableObject, Serializable { @XmlElements({ @XmlElement(name = "selectedLevelIndices", type = Integer.class) }) @DynamicSerializeElement - private List selectedLevelIndices; + private List selectedLevelIndices = new ArrayList(); /** * Copy constructor diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Parameter.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Parameter.java index d21c2dfa57..f92747fedd 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Parameter.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Parameter.java @@ -92,10 +92,6 @@ public class Parameter implements ISerializableObject, Serializable { @DynamicSerializeElement private String fillValue; - @XmlAttribute - @DynamicSerializeElement - private Integer ensemble; - @XmlAttribute @DynamicSerializeElement private String baseType; @@ -124,7 +120,6 @@ public class Parameter implements ISerializableObject, Serializable { this.dataType = copy.dataType; this.missingValue = copy.missingValue; this.fillValue = copy.fillValue; - this.ensemble = copy.ensemble; this.baseType = copy.baseType; // deep copy @@ -265,14 +260,6 @@ public class Parameter implements ISerializableObject, Serializable { return levels; } - public void setEnsemble(Integer ensemble) { - this.ensemble = ensemble; - } - - public Integer getEnsemble() { - return ensemble; - } - public void setFillValue(String fillValue) { this.fillValue = fillValue; } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Provider.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Provider.java index f2775c04a3..5ec9a26b7f 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Provider.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Provider.java @@ -3,11 +3,8 @@ package com.raytheon.uf.common.datadelivery.registry; import static com.google.common.base.Preconditions.checkNotNull; import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.persistence.Transient; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; @@ -22,6 +19,8 @@ import com.raytheon.uf.common.registry.annotations.SlotAttribute; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.time.domain.Durations; +import com.raytheon.uf.common.time.domain.api.IDuration; /** * @@ -62,8 +61,9 @@ public class Provider implements ISerializableObject { * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Feb 16, 2012 dhladky Initial creation + * Feb 16, 2012 dhladky Initial creation * Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects. + * Jan 14, 2013 1286 djohnson Extracted {@link IDuration}. * * * @@ -167,16 +167,9 @@ public class Provider implements ISerializableObject { @SlotAttribute private ServiceType serviceType; - // NOTE: The @XmlElement is on the getter because JAXB must call the setter - // for this value + @XmlElement @DynamicSerializeElement - private String postedFileDelay; - - @Transient - private int postedFileDelayValue = 0; - - @Transient - private TimeUnit postedFileDelayUnits = TimeUnit.HOURS; + private IDuration postedFileDelay = Durations.ZERO; /** * The amount of time that should elapse between HTTP requests while @@ -225,29 +218,10 @@ public class Provider implements ISerializableObject { /** * @return the postedFileDelay */ - @XmlElement(name = "postedFileDelay") - public String getPostedFileDelay() { + public IDuration getPostedFileDelay() { return postedFileDelay; } - /** - * Return the {@link TimeUnit} for the posted file delay. - * - * @return the {@link TimeUnit} - */ - public TimeUnit getPostedFileDelayUnits() { - return postedFileDelayUnits; - } - - /** - * Return the value of the posted file delay. - * - * @return the value - */ - public int getPostedFileDelayValue() { - return postedFileDelayValue; - } - public List getProjection() { return projection; } @@ -321,25 +295,10 @@ public class Provider implements ISerializableObject { * if the string value cannot be parsed into a value and/or * units */ - public void setPostedFileDelay(String postedFileDelay) { + public void setPostedFileDelay(IDuration postedFileDelay) { checkNotNull(postedFileDelay, "postedFileDelay cannot be null!"); this.postedFileDelay = postedFileDelay; - - Matcher matcher = POSTED_FILE_DELAY_PATTERN.matcher(postedFileDelay); - if (matcher.matches()) { - postedFileDelayValue = Integer.parseInt(matcher.group(1)); - String units = matcher.group(2); - postedFileDelayUnits = TimeUnit.valueOf(units); - - if (postedFileDelayUnits == null) { - throw new IllegalArgumentException(units - + " cannot be parsed into a valid units instance!"); - } - } else { - throw new IllegalArgumentException(postedFileDelay - + " cannot be parsed into a valid value and units!"); - } } public void setProjection(List projection) { diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Subscription.java b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Subscription.java index a7eb9581e0..d04aec0db3 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Subscription.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.registry/src/com/raytheon/uf/common/datadelivery/registry/Subscription.java @@ -11,6 +11,8 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; @@ -50,6 +52,7 @@ import com.raytheon.uf.common.time.util.TimeUtil; * Nov 20, 2012 1286 djohnson Add unscheduled. * Dec 12, 2012 1433 bgonzale Refactored Subscription copy ctor into two ctors. * Jan 03, 2013 1441 djohnson Default to no group. + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -66,6 +69,73 @@ import com.raytheon.uf.common.time.util.TimeUtil; Subscription.DATA_SET_SLOT, Subscription.OWNER_SLOT }) public class Subscription implements ISerializableObject, Serializable { + /** Enumeration to use for subscription priorities */ + @XmlEnum + public static enum SubscriptionPriority { + /** High Priority */ + @XmlEnumValue("High") + HIGH("High", 1), + /** Default Priority */ + @XmlEnumValue("Normal") + NORMAL("Normal", 2), + /** Low Priority */ + @XmlEnumValue("Low") + LOW("Low", 3); + + /** Priority Setting */ + private final String priorityName; + + /** Numeric Value of the priority */ + private int priorityValue; + + private SubscriptionPriority(String priorityName, Integer priorityValue) { + this.priorityName = priorityName; + this.priorityValue = priorityValue; + } + + /** + * Get column name. + * + * @return Priority Name + */ + public String getPriorityName() { + return priorityName; + } + + /** + * Get the integer value of the priority + * + * @return The integer value of the priority. + */ + public int getPriorityValue() { + return priorityValue; + } + + @Override + public String toString() { + return priorityName; + } + + /** + * Retrieve the {@link SubscriptionPriority} by its string + * representation. + * + * @param string + * the string representation + * @return the {@link SubscriptionPriority} + */ + public static SubscriptionPriority fromPriorityName(String string) { + for (SubscriptionPriority potential : SubscriptionPriority.values()) { + if (potential.getPriorityName().equals(string)) { + return potential; + } + } + throw new IllegalArgumentException( + "Unable to find priority with priority name [" + string + + "]"); + } + } + private static final long serialVersionUID = -6422673887457060034L; /** Dataset Name slot */ @@ -133,6 +203,7 @@ public class Subscription implements ISerializableObject, Serializable { this.setDataSetType(sub.getDataSetType()); this.setRoute(sub.getRoute()); this.setLatencyInMinutes(sub.getLatencyInMinutes()); + this.setEnsemble(sub.getEnsemble()); } @XmlAttribute @@ -166,7 +237,7 @@ public class Subscription implements ISerializableObject, Serializable { @XmlAttribute @DynamicSerializeElement - private Integer priority; + private SubscriptionPriority priority = SubscriptionPriority.NORMAL; @XmlAttribute @DynamicSerializeElement @@ -243,6 +314,10 @@ public class Subscription implements ISerializableObject, Serializable { @DynamicSerializeElement private ArrayList parameter; + @XmlElement + @DynamicSerializeElement + private Ensemble ensemble; + @XmlAttribute @DynamicSerializeElement private boolean deleted; @@ -359,7 +434,7 @@ public class Subscription implements ISerializableObject, Serializable { * * @return subscription name */ - public Integer getPriority() { + public SubscriptionPriority getPriority() { return priority; } @@ -369,7 +444,7 @@ public class Subscription implements ISerializableObject, Serializable { * @param priority * priority */ - public void setPriority(Integer priority) { + public void setPriority(SubscriptionPriority priority) { this.priority = priority; } @@ -920,4 +995,13 @@ public class Subscription implements ISerializableObject, Serializable { public int getLatencyInMinutes() { return latencyInMinutes; } + + public Ensemble getEnsemble() { + return ensemble; + } + + public void setEnsemble(Ensemble ensemble) { + this.ensemble = ensemble; + } + } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.request/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.datadelivery.request/META-INF/MANIFEST.MF index ff054aa358..9c6d895d32 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.request/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.request/META-INF/MANIFEST.MF @@ -8,4 +8,5 @@ Require-Bundle: com.raytheon.uf.common.auth;bundle-version="1.12.1174", com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174", com.raytheon.uf.common.util;bundle-version="1.12.1174" Export-Package: com.raytheon.uf.common.datadelivery.request;uses:="com.raytheon.uf.common.auth.req,com.raytheon.uf.common.serialization", - com.raytheon.uf.common.datadelivery.request.user;uses:="com.raytheon.uf.common.auth.user" + com.raytheon.uf.common.datadelivery.request.user;uses:="com.raytheon.uf.common.auth.user", + com.raytheon.uf.common.datadelivery.service diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.request/src/com/raytheon/uf/common/datadelivery/service/BaseDataDeliveryService.java b/edexOsgi/com.raytheon.uf.common.datadelivery.request/src/com/raytheon/uf/common/datadelivery/service/BaseDataDeliveryService.java new file mode 100644 index 0000000000..0eec53b63b --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.request/src/com/raytheon/uf/common/datadelivery/service/BaseDataDeliveryService.java @@ -0,0 +1,69 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.datadelivery.service; + +import java.rmi.RemoteException; + +import com.raytheon.uf.common.auth.req.AbstractPrivilegedRequest; +import com.raytheon.uf.common.auth.resp.SuccessfulExecution; +import com.raytheon.uf.common.datadelivery.request.DataDeliveryConstants; +import com.raytheon.uf.common.serialization.ExceptionWrapper; +import com.raytheon.uf.common.serialization.comm.RequestRouter; +import com.raytheon.uf.common.serialization.comm.response.ServerErrorResponse; + +/** + * Base class for services that send requests to the data delivery server. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2013 1441       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class BaseDataDeliveryService { + + /** + * Send a request to the data delivery server. + * + * @param request + * @return + * @throws Exception + */ + protected Object sendRequest(T request) throws Exception { + Object object = RequestRouter.route(request, + DataDeliveryConstants.DATA_DELIVERY_SERVER); + if (object instanceof SuccessfulExecution) { + SuccessfulExecution response = (SuccessfulExecution) object; + return response.getResponse(); + } else { + throw new RemoteException("Error communicating with the server!", + ExceptionWrapper + .unwrapThrowable(((ServerErrorResponse) object) + .getException())); + } + } +} diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/DataSizeUtils.java b/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/DataSizeUtils.java index 0c14d7da1c..0d5b656b19 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/DataSizeUtils.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/DataSizeUtils.java @@ -26,6 +26,7 @@ import org.geotools.geometry.jts.ReferencedEnvelope; import com.raytheon.uf.common.datadelivery.registry.Coverage; import com.raytheon.uf.common.datadelivery.registry.DataSet; +import com.raytheon.uf.common.datadelivery.registry.Ensemble; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet; import com.raytheon.uf.common.datadelivery.registry.Levels; @@ -102,6 +103,8 @@ public class DataSizeUtils { /** Number of forecast hours */ private int numFcstHours = 0; + private int numEnsembleMembers = 0; + /** Envelope */ private ReferencedEnvelope envelope = null; @@ -153,6 +156,7 @@ public class DataSizeUtils { public long getDataSetSizeInBytes() { long l = numRequestedGrids * numFcstHours + * numEnsembleMembers * dataSet.getServiceType().getRequestBytesPerParameterPerLevel( numberOfGridCells); return l; @@ -181,8 +185,15 @@ public class DataSizeUtils { long numCells = griddedCov.getGridCoverage().getNx() * griddedCov.getGridCoverage().getNy(); // Default to 1 forecast hour if not a gridded data set - long fcstHrs = dataSet instanceof GriddedDataSet ? ((GriddedDataSet) dataSet) - .getForecastHours().size() : 1; + long numEns = 1; + long fcstHrs = 1; + if (dataSet instanceof GriddedDataSet) { + GriddedDataSet gDataSet = (GriddedDataSet) dataSet; + fcstHrs = gDataSet.getForecastHours().size(); + if (gDataSet.getEnsemble() != null) { + numEns = gDataSet.getEnsemble().getMemberCount(); + } + } Map paramMap = dataSet.getParameters(); // get the number of grids available @@ -196,7 +207,8 @@ public class DataSizeUtils { numGridsAvailable += (numLevels > 0 ? numLevels : 1); } - fullSize = fcstHrs + fullSize = numEns + * fcstHrs * numGridsAvailable * dataSet.getServiceType() .getRequestBytesPerParameterPerLevel( @@ -295,4 +307,13 @@ public class DataSizeUtils { this.numRequestedGrids = numGrids; } + + public void setNumEnsembleMembers(Ensemble ensemble) { + if (ensemble == null) { + this.numEnsembleMembers = 1; + } else { + this.numEnsembleMembers = ensemble.getSelectedMemberCount(); + } + + } } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/LookupManager.java b/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/LookupManager.java index 20e4bfed21..8fca5267ef 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/LookupManager.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/util/LookupManager.java @@ -42,8 +42,10 @@ import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.common.util.ServiceLoaderUtil; + /** * Lookup table manager * @@ -54,6 +56,7 @@ import com.raytheon.uf.common.util.ServiceLoaderUtil; * ------------ ---------- ----------- -------------------------- * Mar 7, 2011 357 dhladky Initial creation * Oct 27, 2012 1163 dhladky Improved, dynamically create files, Added Units + * Jan 18, 2013 1513 dhladky Level lookup refit. * * * @@ -381,10 +384,9 @@ public class LookupManager { * @throws Exception */ public void modifyLevelLookups(String modelName, double dz, float min, - float max) throws Exception { + float max, List levs) throws Exception { LevelLookup ll = null; - List levs = null; if (levelLookupExists(modelName)) { ll = getLevelsFromFile(modelName); @@ -397,25 +399,33 @@ public class LookupManager { ll = new LevelLookup(); } - if (levs == null) { + boolean gen = false; + + + if (CollectionUtil.isNullOrEmpty(levs)) { ll.setLevelXml(new ArrayList()); levs = ll.getLevelXml(); + gen = true; + } else { + ll.setLevelXml(levs); } - int diff = (int) (max - min); - int total = (int) Math.abs((diff / dz)); - // These add simple place holder level - // identifiers. It is up to the admin - // to add the real values - if (diff < 0) { - for (int i = 0; i <= total; i++) { - double lev = max + i * dz; - levs.add(lev); - } - } else { - for (int i = 0; i <= total; i++) { - double lev = min + i * dz; - levs.add(lev); + if (gen) { + int diff = (int) (max - min); + int total = (int) Math.abs((diff / dz)); + // These add simple place holder level + // identifiers. It is up to the admin + // to add the real values + if (diff < 0) { + for (int i = 0; i <= total; i++) { + double lev = max + i * dz; + levs.add(lev); + } + } else { + for (int i = 0; i <= total; i++) { + double lev = min + i * dz; + levs.add(lev); + } } } @@ -551,4 +561,6 @@ public class LookupManager { return unitXml; } + + } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/xml/RetrievalAttribute.java b/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/xml/RetrievalAttribute.java index c5f48a70ff..860d87acee 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/xml/RetrievalAttribute.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.retrieval/src/com/raytheon/uf/common/datadelivery/retrieval/xml/RetrievalAttribute.java @@ -29,6 +29,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.raytheon.uf.common.datadelivery.registry.Coverage; import com.raytheon.uf.common.datadelivery.registry.CoverageAdapter; +import com.raytheon.uf.common.datadelivery.registry.Ensemble; import com.raytheon.uf.common.datadelivery.registry.Parameter; import com.raytheon.uf.common.datadelivery.registry.Time; import com.raytheon.uf.common.serialization.ISerializableObject; @@ -100,6 +101,10 @@ public class RetrievalAttribute implements ISerializableObject, Serializable { @DynamicSerializeElement private Time time; + @XmlElement + @DynamicSerializeElement + private Ensemble ensemble; + @XmlElement(name = "provider") @DynamicSerializeElement private String provider; @@ -156,4 +161,12 @@ public class RetrievalAttribute implements ISerializableObject, Serializable { return subName; } + public Ensemble getEnsemble() { + return ensemble; + } + + public void setEnsemble(Ensemble ensemble) { + this.ensemble = ensemble; + } + } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/.classpath b/edexOsgi/com.raytheon.uf.common.datadelivery.service/.classpath new file mode 100644 index 0000000000..5fb20a28e5 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/.project b/edexOsgi/com.raytheon.uf.common.datadelivery.service/.project new file mode 100644 index 0000000000..0cee36f7f5 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.common.datadelivery.service + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/.settings/org.eclipse.jdt.core.prefs b/edexOsgi/com.raytheon.uf.common.datadelivery.service/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..28b23bdfac --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Tue Feb 14 11:27:19 CST 2012 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.datadelivery.service/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..242708d98c --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: com.raytheon.uf.common.datadelivery.service +Bundle-SymbolicName: com.raytheon.uf.common.datadelivery.service +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: RAYTHEON +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: javax.persistence +Require-Bundle: + com.raytheon.uf.common.serialization;bundle-version="1.12.1174", + com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174", + com.raytheon.uf.common.datadelivery.registry;bundle-version="1.0.0", + com.raytheon.uf.common.status;bundle-version="1.12.1174", + com.raytheon.uf.common.datadelivery.request;bundle-version="1.0.0", + com.raytheon.uf.common.registry.ebxml;bundle-version="1.0.0", + com.raytheon.uf.common.auth;bundle-version="1.12.1174" +Export-Package: + com.raytheon.uf.common.datadelivery.service + + diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/build.properties b/edexOsgi/com.raytheon.uf.common.datadelivery.service/build.properties new file mode 100644 index 0000000000..9f81850f2c --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/build.properties @@ -0,0 +1,6 @@ +source.. = src/,\ + res/ +output.. = bin/ +bin.includes = META-INF/,\ + res/,\ + . \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/com.raytheon.uf.common.datadelivery.service.ecl b/edexOsgi/com.raytheon.uf.common.datadelivery.service/com.raytheon.uf.common.datadelivery.service.ecl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/res/spring/datadelivery-service.xml b/edexOsgi/com.raytheon.uf.common.datadelivery.service/res/spring/datadelivery-service.xml new file mode 100644 index 0000000000..67c539da2f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/res/spring/datadelivery-service.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/ApprovedPendingSubscriptionNotificationRequest.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ApprovedPendingSubscriptionNotificationRequest.java similarity index 96% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/ApprovedPendingSubscriptionNotificationRequest.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ApprovedPendingSubscriptionNotificationRequest.java index 3cae3fca16..3f28d090b0 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/ApprovedPendingSubscriptionNotificationRequest.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ApprovedPendingSubscriptionNotificationRequest.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/ApprovedPendingSubscriptionNotificationResponse.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ApprovedPendingSubscriptionNotificationResponse.java similarity index 95% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/ApprovedPendingSubscriptionNotificationResponse.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ApprovedPendingSubscriptionNotificationResponse.java index 97abe5e0d1..af357e0b26 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/ApprovedPendingSubscriptionNotificationResponse.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ApprovedPendingSubscriptionNotificationResponse.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/BaseSubscriptionNotificationRequest.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/BaseSubscriptionNotificationRequest.java similarity index 97% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/BaseSubscriptionNotificationRequest.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/BaseSubscriptionNotificationRequest.java index 99cbd26efe..3670927e41 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/BaseSubscriptionNotificationRequest.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/BaseSubscriptionNotificationRequest.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.serialization.ISerializableObject; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/BaseSubscriptionNotificationResponse.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/BaseSubscriptionNotificationResponse.java similarity index 82% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/BaseSubscriptionNotificationResponse.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/BaseSubscriptionNotificationResponse.java index bdc515c04a..b879907bc9 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/BaseSubscriptionNotificationResponse.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/BaseSubscriptionNotificationResponse.java @@ -17,9 +17,10 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.handlers.IBaseSubscriptionHandler; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -27,17 +28,18 @@ import com.raytheon.uf.common.serialization.comm.IServerRequest; /** * Base abstract class for the subscription notification response. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Sep 20, 2012    1157    mpduff      Initial creation
- *
+ * Jan 17, 2013 1501       djohnson     Allow a response to specify the subscription handler.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -85,4 +87,11 @@ public abstract class BaseSubscriptionNotificationResponse getSubscriptionHandler(); } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/DeniedPendingSubscriptionNotificationRequest.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/DeniedPendingSubscriptionNotificationRequest.java similarity index 96% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/DeniedPendingSubscriptionNotificationRequest.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/DeniedPendingSubscriptionNotificationRequest.java index 08dcacf8da..d5183fa270 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/DeniedPendingSubscriptionNotificationRequest.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/DeniedPendingSubscriptionNotificationRequest.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/DeniedPendingSubscriptionNotificationResponse.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/DeniedPendingSubscriptionNotificationResponse.java similarity index 96% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/DeniedPendingSubscriptionNotificationResponse.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/DeniedPendingSubscriptionNotificationResponse.java index 3a3c60722f..cb7cfc7971 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/DeniedPendingSubscriptionNotificationResponse.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/DeniedPendingSubscriptionNotificationResponse.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/GroupDefinitionService.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/GroupDefinitionService.java new file mode 100644 index 0000000000..ed7777375d --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/GroupDefinitionService.java @@ -0,0 +1,75 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.datadelivery.service; + +import com.raytheon.uf.common.datadelivery.registry.GroupDefinition; +import com.raytheon.uf.common.datadelivery.registry.GroupDefinitionServiceRequest; +import com.raytheon.uf.common.datadelivery.registry.GroupDefinitionServiceRequest.Type; +import com.raytheon.uf.common.registry.handler.RegistryHandlerException; + +/** + * Base implementation of {@link IGroupDefinitionService}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2013 1441       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class GroupDefinitionService extends + BaseDataDeliveryService implements + IGroupDefinitionService { + + /** + * {@inheritDoc} + * @throws Exception + */ + @Override + public void deleteGroupDefinition(GroupDefinition group) + throws RegistryHandlerException { + GroupDefinitionServiceRequest request = new GroupDefinitionServiceRequest(); + request.setGroup(group); + request.setType(Type.DELETE); + + sendRequest(request); + } + + /** + * {@inheritDoc} + */ + @Override + protected Object sendRequest(GroupDefinitionServiceRequest request) + throws RegistryHandlerException { + try { + return super.sendRequest(request); + } catch (Exception e) { + throw new RegistryHandlerException(e); + } + } + +} diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/retrieval/util/NullXmlWriter.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/IGroupDefinitionService.java similarity index 57% rename from tests/unit/com/raytheon/uf/common/datadelivery/retrieval/util/NullXmlWriter.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/IGroupDefinitionService.java index 38a044e069..d99f0a96bb 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/retrieval/util/NullXmlWriter.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/IGroupDefinitionService.java @@ -17,44 +17,36 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.retrieval.util; +package com.raytheon.uf.common.datadelivery.service; -import com.raytheon.uf.common.datadelivery.retrieval.xml.LevelLookup; -import com.raytheon.uf.common.datadelivery.retrieval.xml.ParameterLookup; +import com.raytheon.uf.common.datadelivery.registry.GroupDefinition; +import com.raytheon.uf.common.registry.handler.RegistryHandlerException; /** - * Makes parser created XML not write out in test + * Defines the service to interact with {@link GroupDefinition} objects. * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Jan 10, 2013            djohnson     Initial creation
- *
+ * Jan 18, 2013 1441       djohnson     Initial creation
+ * 
  * 
- * + * * @author djohnson - * @version 1.0 + * @version 1.0 */ -public class NullXmlWriter implements LevelXmlWriter, ParameterXmlWriter { - +public interface IGroupDefinitionService { /** - * {@inheritDoc} + * Delete the group definition. + * + * @param group + * the group + * @throws RegistryHandlerException */ - @Override - public void writeParameterXml(ParameterLookup pl, String modelName) - throws Exception { - } - - /** - * {@inheritDoc} - */ - @Override - public void writeLevelXml(LevelLookup ll, String modelName) - throws Exception { - } - + void deleteGroupDefinition(GroupDefinition group) + throws RegistryHandlerException; } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/ISubscriptionNotificationService.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ISubscriptionNotificationService.java similarity index 98% rename from cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/ISubscriptionNotificationService.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ISubscriptionNotificationService.java index 98216ec787..4394219ff2 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/ISubscriptionNotificationService.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/ISubscriptionNotificationService.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.viz.datadelivery.subscription; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.datadelivery.registry.InitialPendingSubscription; import com.raytheon.uf.common.datadelivery.registry.Subscription; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/PendingSubscriptionNotificationRequest.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/PendingSubscriptionNotificationRequest.java similarity index 96% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/PendingSubscriptionNotificationRequest.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/PendingSubscriptionNotificationRequest.java index a531ea5629..af4cc15ad5 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/PendingSubscriptionNotificationRequest.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/PendingSubscriptionNotificationRequest.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.datadelivery.registry.InitialPendingSubscription; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/PendingSubscriptionNotificationResponse.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/PendingSubscriptionNotificationResponse.java similarity index 71% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/PendingSubscriptionNotificationResponse.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/PendingSubscriptionNotificationResponse.java index 46b9f011b7..f88a77832f 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/PendingSubscriptionNotificationResponse.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/PendingSubscriptionNotificationResponse.java @@ -17,24 +17,27 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.datadelivery.registry.InitialPendingSubscription; +import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; +import com.raytheon.uf.common.datadelivery.registry.handlers.IBaseSubscriptionHandler; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; /** * PendingSubscriptionNotificationResponse object. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Sep 20, 2012            mpduff     Initial creation
- *
+ * Jan 17, 2013 1501       djohnson     Allow a response to specify the subscription handler.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -42,4 +45,12 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; public class PendingSubscriptionNotificationResponse extends BaseSubscriptionNotificationResponse { + /** + * {@inheritDoc} + */ + @Override + public IBaseSubscriptionHandler getSubscriptionHandler() { + return DataDeliveryHandlers.getPendingSubscriptionHandler(); + } + } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SendToServerSubscriptionNotificationService.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SendToServerSubscriptionNotificationService.java similarity index 88% rename from cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SendToServerSubscriptionNotificationService.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SendToServerSubscriptionNotificationService.java index 8206745bcf..ef4645d3e2 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/SendToServerSubscriptionNotificationService.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SendToServerSubscriptionNotificationService.java @@ -17,20 +17,15 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.viz.datadelivery.subscription; +package com.raytheon.uf.common.datadelivery.service; -import com.raytheon.uf.common.datadelivery.event.notification.ApprovedPendingSubscriptionNotificationRequest; -import com.raytheon.uf.common.datadelivery.event.notification.BaseSubscriptionNotificationRequest; -import com.raytheon.uf.common.datadelivery.event.notification.DeniedPendingSubscriptionNotificationRequest; -import com.raytheon.uf.common.datadelivery.event.notification.PendingSubscriptionNotificationRequest; -import com.raytheon.uf.common.datadelivery.event.notification.SubscriptionNotificationRequest; import com.raytheon.uf.common.datadelivery.registry.InitialPendingSubscription; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.request.DataDeliveryConstants; +import com.raytheon.uf.common.serialization.comm.RequestRouter; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.requests.ThriftClient; /** * Implementation of {@link ISubscriptionNotificationService} that sends the @@ -42,7 +37,9 @@ import com.raytheon.uf.viz.core.requests.ThriftClient; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 4, 2013 1441 djohnson Initial creation + * Jan 04, 2013 1441 djohnson Initial creation + * Jan 17, 2013 1501 djohnson Route to datadelivery. + * Jan 21, 2013 1501 djohnson Include subscription on all requests. * * * @@ -181,6 +178,7 @@ public class SendToServerSubscriptionNotificationService implements req.setCategory("Subscription Approval Denied"); req.setPriority(2); req.setId(subscription.getId()); + req.setSubscription(subscription); sendRequest(req); } @@ -207,13 +205,13 @@ public class SendToServerSubscriptionNotificationService implements */ @Override public void sendSubscriptionActivatedNotification( - Subscription subscription, - String username) { + Subscription subscription, String username) { SubscriptionNotificationRequest req = new SubscriptionNotificationRequest(); req.setUserId(username); req.setCategory("Subscription"); req.setPriority(3); req.setMessage(subscription.getName() + " Activated"); + req.setSubscription(subscription); sendRequest(req); } @@ -223,13 +221,13 @@ public class SendToServerSubscriptionNotificationService implements */ @Override public void sendSubscriptionDeactivatedNotification( - Subscription subscription, - String username) { + Subscription subscription, String username) { SubscriptionNotificationRequest req = new SubscriptionNotificationRequest(); req.setUserId(username); req.setCategory("Subscription"); req.setPriority(3); req.setMessage(subscription.getName() + " Deactivated"); + req.setSubscription(subscription); sendRequest(req); } @@ -241,8 +239,9 @@ public class SendToServerSubscriptionNotificationService implements */ private void sendRequest(BaseSubscriptionNotificationRequest req) { try { - ThriftClient.sendRequest(req); - } catch (VizException e) { + RequestRouter + .route(req, DataDeliveryConstants.DATA_DELIVERY_SERVER); + } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); } } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/SubscriptionNotificationRequest.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SubscriptionNotificationRequest.java similarity index 96% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/SubscriptionNotificationRequest.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SubscriptionNotificationRequest.java index 18774bdd64..261aade582 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/SubscriptionNotificationRequest.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SubscriptionNotificationRequest.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/SubscriptionNotificationResponse.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SubscriptionNotificationResponse.java similarity index 72% rename from edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/SubscriptionNotificationResponse.java rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SubscriptionNotificationResponse.java index 61239fe9e9..b0c5d73482 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.event/src/com/raytheon/uf/common/datadelivery/event/notification/SubscriptionNotificationResponse.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/SubscriptionNotificationResponse.java @@ -17,28 +17,39 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.event.notification; +package com.raytheon.uf.common.datadelivery.service; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; +import com.raytheon.uf.common.datadelivery.registry.handlers.IBaseSubscriptionHandler; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; /** * SubscriptionNotificationResponse object. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Jun 25, 2012            mpduff     Initial creation.
  * Aug 21, 2012     712    mpduff     Add a Subscription Object.
+ * Jan 17, 2013 1501       djohnson     Allow a response to specify the subscription handler.
  * 
- * + * * @author mpduff * @version 1.0 */ @DynamicSerialize public class SubscriptionNotificationResponse extends BaseSubscriptionNotificationResponse{ + + /** + * {@inheritDoc} + */ + @Override + public IBaseSubscriptionHandler getSubscriptionHandler() { + return DataDeliveryHandlers.getSubscriptionHandler(); + } } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject index 63d9a8ae0f..441e54b68a 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -1,8 +1,2 @@ com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord -com.raytheon.uf.common.dataplugin.ffmp.FFMPBasin -com.raytheon.uf.common.dataplugin.ffmp.FFMPVirtualGageBasin -com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceBasin -com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData -com.raytheon.uf.common.dataplugin.ffmp.SourceBinList -com.raytheon.uf.common.dataplugin.ffmp.SourceBin -com.raytheon.uf.common.dataplugin.ffmp.SourceBinEntry \ No newline at end of file + diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPAggregateRecord.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPAggregateRecord.java new file mode 100644 index 0000000000..fc056e83a5 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPAggregateRecord.java @@ -0,0 +1,104 @@ +package com.raytheon.uf.common.dataplugin.ffmp; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Cache Record implementation for FFMP plugin + * Eventually this will become a full record implementation + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 01/27/13     1478        D. Hladky   Created to reduce memory and disk read/writes for FFMP
+ * 
+ * 
+ * + * @author dhladky + * @version 1 + */ + +@DynamicSerialize +public class FFMPAggregateRecord implements ISerializableObject { + + + private static final long serialVersionUID = 76774564363471L; + + /** + * + */ + public FFMPAggregateRecord() { + + } + + @DynamicSerializeElement + private HashMap basinsMap = new HashMap(); + + @DynamicSerializeElement + private List times = new ArrayList(); + + public void setTimes(List times) { + this.times = times; + } + + public List getTimes() { + return times; + } + + public void setBasinsMap(HashMap basinsMap) { + this.basinsMap = basinsMap; + } + + public HashMap getBasinsMap() { + return basinsMap; + } + + /** + * Add a basin Data Cache object + * @param cacheData + */ + public void setBasinData(FFMPBasinData cacheData) { + basinsMap.put(cacheData.getHucLevel(), cacheData); + } + + /** + * Gets the BasinData object + * @param huc + * @return + */ + public FFMPBasinData getBasinData(String huc) { + if (basinsMap.containsKey(huc)) { + return basinsMap.get(huc); + } + return null; + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasin.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasin.java index 273200bba5..74c4d874de 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasin.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasin.java @@ -22,14 +22,11 @@ package com.raytheon.uf.common.dataplugin.ffmp; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; +import java.util.List; import java.util.Map.Entry; import java.util.TreeMap; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import javax.persistence.Transient; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; @@ -45,30 +42,49 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 06/22/09 2152 D. Hladky Initial release + * 01/27/13 1478 D. Hladky Added support for writing aggregate record cache * * * * @author dhladky * @version 1 */ -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class FFMPBasin implements ISerializableObject, Cloneable { /** pfafstetter id(key) in GIS **/ @DynamicSerializeElement - @XmlElement protected Long pfaf; /** boolean aggregator **/ @DynamicSerializeElement - @XmlAttribute protected boolean aggregated = false; - @DynamicSerializeElement - @XmlElement + /** object used in calculations + * not serialized + **/ + @Transient protected TreeMap values; + + /** object used for serialization **/ + @DynamicSerializeElement + public float[] cacheValues; + + /** + * Get the float array of serialized values + * @return + */ + public float[] getCacheValues() { + return cacheValues; + } + + /** + * Set the serialized array of cache values + * @param cacheValues + */ + public void setCacheValues(float[] cacheValues) { + this.cacheValues = cacheValues; + } /** * @return the pfaf_id @@ -326,14 +342,23 @@ public class FFMPBasin implements ISerializableObject, Cloneable { } /** - * No arg hibernate constructor + * No arg serial constructor */ public FFMPBasin() { + values = new TreeMap(new Comparator() { + @Override + public int compare(Date o1, Date o2) { + // Null checks? + return (int)(o2.getTime() - o1.getTime()) ; + } + }); } /** - * useful constructor + * Useful constructor + * @param pfaf + * @param aggregated */ public FFMPBasin(Long pfaf, boolean aggregated) { setPfaf(pfaf); @@ -342,11 +367,45 @@ public class FFMPBasin implements ISerializableObject, Cloneable { @Override public int compare(Date o1, Date o2) { // Null checks? - return (int)Math.signum(o2.getTime() - o1.getTime()) ; + return (int)(o2.getTime() - o1.getTime()) ; } }); } + + /** + * Populates the values from the cache + * + * @param times + */ + public void populate(List times) { + // safe to avoid Array Index Exceptions / shouldn't happen but..... + + if (cacheValues != null && (times.size() == cacheValues.length)) { + + int i = 0; + for (Long time : times) { + values.put(new Date(time), cacheValues[i]); + i++; + } + //System.out.println("populated :"+i+" pfaf : "+pfaf); + } + } + + /** + * populates the serialized array + */ + public void setCache() { + + cacheValues = new float[values.size()]; + int i = 0; + + for (Date date: values.descendingKeySet()) { + cacheValues[i] = values.get(date); + i++; + } + //System.out.println("wrote :"+i+" pfaf : "+pfaf); + } /** * purge out old entries diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasinData.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasinData.java index 3255488b3d..0800b8b008 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasinData.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPBasinData.java @@ -22,11 +22,7 @@ package com.raytheon.uf.common.dataplugin.ffmp; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; @@ -42,14 +38,13 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 06/22/09 2152 D. Hladky Initial release + * 01/27/13 1478 D. Hladky Added support for write of aggregate record cache * * * * @author dhladky * @version 1 */ -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class FFMPBasinData implements ISerializableObject { @@ -62,11 +57,9 @@ public class FFMPBasinData implements ISerializableObject { // defaults @DynamicSerializeElement - @XmlElement private String hucLevel; @DynamicSerializeElement - @XmlElement private HashMap basins = new HashMap(); /** @@ -86,7 +79,7 @@ public class FFMPBasinData implements ISerializableObject { } /** - * Used only internally + * get the basin map * * @return */ @@ -95,7 +88,7 @@ public class FFMPBasinData implements ISerializableObject { } /** - * DONT USE THIS EVER!!!!! + * Sets the basin map * * @param basins */ @@ -545,5 +538,25 @@ public class FFMPBasinData implements ISerializableObject { basin.purgeData(date); } } + + /** + * populates data from the cache + * + * @param times + */ + public void populate(List times) { + for (FFMPBasin basin : basins.values()) { + basin.populate(times); + } + } + + /** + * populates the serialized array/objects + */ + public void setCache() { + for (FFMPBasin basin : basins.values()) { + basin.setCache(); + } + } } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPCacheRecord.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPCacheRecord.java index 400167c282..bccf12b826 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPCacheRecord.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPCacheRecord.java @@ -1,4 +1,23 @@ package com.raytheon.uf.common.dataplugin.ffmp; +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ import java.awt.Point; import java.io.IOException; @@ -210,16 +229,16 @@ public class FFMPCacheRecord extends FFMPRecord { } /** - * Buddy File reader + * Cache File reader * * @param basins * @param hucName */ - public void setBasinBuddyData(FFMPBasinData basins, String hucName) { + public void setCacheData(FFMPBasinData basins, String hucName) { if (getBasinData(hucName) != null) { basins = getBasinData(hucName, true); - //System.out.println("Adding pieces Buddy Data: "+hucName+" "+getSourceName()); + //System.out.println("Adding Cache Data: "+hucName+" "+getSourceName()); synchronized (basins) { for (Entry entry : basins.getBasins() @@ -442,8 +461,7 @@ public class FFMPCacheRecord extends FFMPRecord { } catch (Throwable e) { statusHandler.handle(Priority.PROBLEM, "ERROR Retrieving Map for URI: " + uri - + "..." + huc); - e.printStackTrace(); + + "..." + huc, e); } } } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPDataContainer.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPDataContainer.java index dc84912457..3cfecdc66d 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPDataContainer.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPDataContainer.java @@ -20,9 +20,9 @@ package com.raytheon.uf.common.dataplugin.ffmp; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -33,7 +33,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; /** - * FFTI Data Container + * FFMP Data Container * *
  * 
@@ -43,7 +43,8 @@ import com.raytheon.uf.common.status.UFStatus;
  * ------------ ----------  ----------- --------------------------
  * 03/31/11     5489     D. Hladky   Initial release
  * 07/31/12     578      D.Hladky    finished it
- * 09/27/12		DR 15471  G.Zhang	 Fixed ConcurrentModificationException
+ * 09/27/12		DR 15471 G.Zhang	 Fixed ConcurrentModificationException
+ * 01/27/13     1478     D. Hladky   Re-worked to help with memory size and NAS read write stress
  * 
* * @author dhladky @@ -62,15 +63,24 @@ public class FFMPDataContainer { private String filePath = null; public FFMPDataContainer() { - // public unused constructor + } + /** + * Usual constructor + * @param sourceName + */ public FFMPDataContainer(String sourceName) { this.sourceName = sourceName; basinDataMap.put("ALL", new FFMPBasinData("ALL")); // System.out.println("Creating source: " + sourceName); } + /** + * special constuctor + * @param sourceName + * @param hucs + */ public FFMPDataContainer(String sourceName, ArrayList hucs) { // System.out.println("Creating source with hucs: " + sourceName); this.sourceName = sourceName; @@ -78,6 +88,21 @@ public class FFMPDataContainer { basinDataMap.put(huc, new FFMPBasinData(huc)); } } + /** + * new container first time read in from cache + * @param sourceName + * @param hucs + * @param record + */ + public FFMPDataContainer(String sourceName, ArrayList hucs, FFMPAggregateRecord record) { + // System.out.println("Creating source with hucs: " + sourceName); + this.sourceName = sourceName; + for (String huc : hucs) { + FFMPBasinData basinData = record.getBasinData(huc); + basinData.populate(record.getTimes()); + basinDataMap.put(huc, basinData); + } + } /** * Adds to the cache @@ -400,7 +425,7 @@ public class FFMPDataContainer { * @param barrierTime * @return */ - public ArrayList getOrderedTimes(Date barrierTime) { + public List getOrderedTimes(Date barrierTime) { ArrayList orderedTimes = new ArrayList(); try { HashMap basins = getBasinData("ALL").getBasins(); @@ -414,7 +439,32 @@ public class FFMPDataContainer { } } - Collections.reverse(orderedTimes); + return orderedTimes; + } + } + } catch (Exception e) { + statusHandler.debug("No ordered times available..." + + getSourceName()); + } + + return null; + } + + /** + * Gets the list of times for serialization + * @return + */ + public List getOrderedTimes() { + ArrayList orderedTimes = new ArrayList(); + try { + HashMap basins = getBasinData("ALL").getBasins(); + + synchronized (basins) { + for (Entry entry : basins.entrySet()) { + FFMPBasin basin = entry.getValue(); + for (Date time : basin.getValues().descendingKeySet()) { + orderedTimes.add(time.getTime()); + } return orderedTimes; } @@ -422,18 +472,22 @@ public class FFMPDataContainer { } catch (Exception e) { statusHandler.debug("No ordered times available..." + getSourceName()); - return null; } return null; } + /** + * Gets the source name for this Data Container + * @return + */ public String getSourceName() { return sourceName; } - /* - * clean up old junk + /** + * Clean up old junk + * @param backDate */ public void purge(Date backDate) { for (String huc : basinDataMap.keySet()) { @@ -442,27 +496,33 @@ public class FFMPDataContainer { } /** - * maybe this will work + * Sets the Cache data for this container * - * @param basins - * @param hucName + * @param cacheRecord */ - public void setBasinBuddyData(FFMPBasinData basins, String hucName) { + public void setCacheData(FFMPAggregateRecord cacheRecord) { - for (Entry entry : basins.getBasins().entrySet()) { - FFMPBasin basin = getBasinData(hucName).get(entry.getKey()); - if (basin != null) { - if (basin instanceof FFMPGuidanceBasin) { - FFMPGuidanceBasin gbasin = (FFMPGuidanceBasin) basin; - gbasin.getGuidValues().putAll( - ((FFMPGuidanceBasin) entry.getValue()) - .getGuidValues()); + // create a record from the cache record + FFMPRecord record = new FFMPRecord(cacheRecord); + + for (Entry dentry : record.getBasinsMap() + .entrySet()) { + for (Entry entry : dentry.getValue().getBasins() + .entrySet()) { + FFMPBasin basin = entry.getValue(); + if (basin != null) { + if (basin instanceof FFMPGuidanceBasin) { + FFMPGuidanceBasin gbasin = (FFMPGuidanceBasin) basin; + gbasin.getGuidValues().putAll( + ((FFMPGuidanceBasin) entry.getValue()) + .getGuidValues()); + } else { + basin.getValues().putAll(entry.getValue().getValues()); + } } else { - basin.getValues().putAll(entry.getValue().getValues()); + syncPut(getBasinData(dentry.getKey()), entry.getKey(), + entry.getValue()); } - } else { - syncPut(getBasinData(hucName), entry.getKey(), entry.getValue()); - //getBasinData(hucName).put(entry.getKey(), entry.getValue()); } } } @@ -523,4 +583,13 @@ public class FFMPDataContainer { basins.put(key, value); } } + + /** + * Gets the basin data map + * @return + */ + public ConcurrentHashMap getBasinMap() { + return basinDataMap; + } + } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGap.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGap.java index 3e97903f0d..d0490fec2d 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGap.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGap.java @@ -1,4 +1,23 @@ package com.raytheon.uf.common.dataplugin.ffmp; +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ /** * gap for FFMP @@ -10,6 +29,7 @@ package com.raytheon.uf.common.dataplugin.ffmp; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 03/03/11 7334 D. Hladky Initial release + * 01/27/13 1478 D. Hladky Added use of constants for calculations * * * @@ -19,6 +39,9 @@ package com.raytheon.uf.common.dataplugin.ffmp; import java.util.ArrayList; import java.util.Date; +import java.util.List; + +import com.raytheon.uf.common.time.util.TimeUtil; public class FFMPGap { @@ -62,21 +85,25 @@ public class FFMPGap { } /** - * Gets the GAP calculation for an FFMP source + * Get the gaps in the FFMP data * - * @return Array of Gap data + * @param times + * @param expirationTime + * @param barrierTime + * @param mostRecentTime + * @return */ - public static ArrayList getGaps(ArrayList times, + public static List getGaps(List times, long expirationTime, Date barrierTime, Date mostRecentTime) { ArrayList gaps = new ArrayList(); - long gapStep = expirationTime * 60 * 1000; + long gapStep = expirationTime * TimeUtil.MILLIS_PER_MINUTE; Date prevTime = null; // System.out.println("Calling getGaps()...Recent Time: " + mostRecentTime // + " BarrierTime: " + barrierTime); if (times.size() == 1) { FFMPGap gap = new FFMPGap(); long totalMillis = mostRecentTime.getTime() - barrierTime.getTime() - gapStep; - float gapMinutes = (totalMillis)/(60 * 1000); + float gapMinutes = totalMillis/TimeUtil.MILLIS_PER_MINUTE; if (gapMinutes < 0.0) { gapMinutes = 0.0f; } @@ -100,7 +127,7 @@ public class FFMPGap { FFMPGap gap = new FFMPGap(prevTime, time); // convert to minutes and set gap // Need to subtract the expirationTime from the gapTime as well - gap.setGap((gapTime - gapStep) / (60 * 1000)); + gap.setGap((gapTime - gapStep) / TimeUtil.MILLIS_PER_MINUTE); gaps.add(gap); } prevTime = time; diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceBasin.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceBasin.java index 3366acac1c..7b0c124115 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceBasin.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceBasin.java @@ -4,13 +4,10 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.TreeMap; import javax.persistence.Transient; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; import com.raytheon.uf.common.monitor.config.FFFGDataMgr; import com.raytheon.uf.common.serialization.ISerializableObject; @@ -27,22 +24,21 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 08/22/10 3437 D. Hladky Initial release + * 01/17/13 1478 D. Hladky Removed un-needed XML attributes * * * * @author dhladky * @version 1 */ -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class FFMPGuidanceBasin extends FFMPBasin implements ISerializableObject { + public FFMPGuidanceBasin() { } @DynamicSerializeElement - @XmlElement protected TreeMap> guidValues; @Transient @@ -411,7 +407,10 @@ public class FFMPGuidanceBasin extends FFMPBasin implements ISerializableObject } /** - * useful constructor + * Constructor used in producing a new GuidanceBasin + * + * @param pfaf + * @param aggregated */ public FFMPGuidanceBasin(Long pfaf, boolean aggregated) { setPfaf(pfaf); @@ -457,5 +456,15 @@ public class FFMPGuidanceBasin extends FFMPBasin implements ISerializableObject } return buff.toString(); } - + + public void populate(List times) { + // does nothing here, don't need to populate anything. + } + + /** + * populates the serialized array + */ + public void setCache() { + // does nothing here, this class is serialized as is. + } } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceInterpolation.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceInterpolation.java index a82f203b9a..1bc43a46d4 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceInterpolation.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPGuidanceInterpolation.java @@ -30,6 +30,7 @@ import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager; import com.raytheon.uf.common.monitor.xml.ProductRunXML; import com.raytheon.uf.common.monitor.xml.ProductXML; import com.raytheon.uf.common.monitor.xml.SourceXML; +import com.raytheon.uf.common.time.util.TimeUtil; /** * Guidance Interpolation @@ -39,6 +40,7 @@ import com.raytheon.uf.common.monitor.xml.SourceXML; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 29 Jan, 2010 3915 dhladky Initial creation + * 01/27/13 1478 dhladky Added use of constants * * * @author dhladky @@ -258,7 +260,7 @@ public class FFMPGuidanceInterpolation { getSource(orderedHours.get(index)), null, manager.getSource(source).getExpirationMinutes( - siteKey) * 60 * 1000); + siteKey) * TimeUtil.MILLIS_PER_MINUTE); if (dman.isExpired() == false) { thisVal = dman.adjustValue(thisVal, diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPRecord.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPRecord.java index 402d1937eb..08d86bde13 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPRecord.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPRecord.java @@ -25,6 +25,7 @@ import java.io.FileNotFoundException; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map.Entry; import javax.persistence.Column; @@ -66,6 +67,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 06/03/09 2521 D. Hladky Initial release + * 01/27/13 1478 D. Hladky OUN memory help * * * @@ -758,5 +760,39 @@ public class FFMPRecord extends ServerSpecificPersistablePluginDataObject public String getSiteKey() { return siteKey; } + + /** + * Get the fully cache ready object + * @param fileName + * @return + */ + public FFMPAggregateRecord getCacheRecord() { + FFMPAggregateRecord fdcr = new FFMPAggregateRecord(); + + for (Entry entry: basinsMap.entrySet()) { + fdcr.setBasinData(entry.getValue()); + } + + return fdcr; + } + + /** + * Creates and populates a version of this record from a cache record + * + * @param fdcr + */ + public FFMPRecord(FFMPAggregateRecord fdcr) { + + List times = fdcr.getTimes(); + + for (Entry entry : fdcr.getBasinsMap() + .entrySet()) { + + FFMPBasinData fbd = entry.getValue(); + // Keep in mind times can be null, Guidance basins are like that + fbd.populate(times); + setBasinData(fbd, fbd.getHucLevel()); + } + } } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPVirtualGageBasin.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPVirtualGageBasin.java index 1fa7301a13..2547fa428b 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPVirtualGageBasin.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/FFMPVirtualGageBasin.java @@ -1,13 +1,28 @@ package com.raytheon.uf.common.dataplugin.ffmp; +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ import java.util.Comparator; import java.util.Date; import java.util.TreeMap; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -21,14 +36,13 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 02may10 3937 dhladky Setup + * 01/27/13 1478 dhladky Removed un-needed XML annotations * * * * @author dhladky * @version 1.0 */ -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class FFMPVirtualGageBasin extends FFMPBasin implements ISerializableObject { diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBin.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBin.java index 940fec8a20..1982944bdb 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBin.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBin.java @@ -1,12 +1,26 @@ package com.raytheon.uf.common.dataplugin.ffmp; +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ import java.util.ArrayList; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -22,28 +36,25 @@ import com.vividsolutions.jts.geom.Coordinate; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 10/22/10 6581 D. Hladky Initial release + * 01/27/13 1478 D. Hladky Removed un needed XML annotations * * * * @author dhladky * @version 1 */ -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) + @DynamicSerialize public class SourceBin implements ISerializableObject { /** sourceName and dataKey **/ @DynamicSerializeElement - @XmlElement public double[] lats; @DynamicSerializeElement - @XmlElement public double[] lons; @DynamicSerializeElement - @XmlElement public double[] areaPercent; public SourceBin() { diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinEntry.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinEntry.java index 8618eeb16a..1e8ae77c38 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinEntry.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinEntry.java @@ -1,24 +1,53 @@ package com.raytheon.uf.common.dataplugin.ffmp; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.vividsolutions.jts.geom.Coordinate; +/** + * FFMP source binning entry object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 01/27/13     1478        D. Hladky   Removed un needed XML annotations
+ * 
+ * 
+ * + * @author dhladky + * @version 1 + */ + @DynamicSerialize -@XmlAccessorType(XmlAccessType.NONE) public class SourceBinEntry { /** sourceName and dataKey **/ @DynamicSerializeElement - @XmlElement public Coordinate coor; @DynamicSerializeElement - @XmlElement public double area; public Coordinate getCoor() { diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinList.java b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinList.java index d8b2d1b2ac..96bfdff689 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinList.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ffmp/src/com/raytheon/uf/common/dataplugin/ffmp/SourceBinList.java @@ -1,12 +1,26 @@ package com.raytheon.uf.common.dataplugin.ffmp; +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ import java.util.HashMap; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -22,24 +36,21 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 10/22/10 6581 D. Hladky Initial release + * 01/27/13 1478 D. Hladky Removed un needed XML annotations * * * * @author dhladky * @version 1 */ -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class SourceBinList implements ISerializableObject { /** sourceName and dataKey **/ @DynamicSerializeElement - @XmlElement public String sourceId; @DynamicSerializeElement - @XmlElement public HashMap sourceMap; public SourceBinList() { diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/DatabaseID.java b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/DatabaseID.java index 9cdce457d8..3e1e00fb62 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/DatabaseID.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/DatabaseID.java @@ -50,6 +50,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdap * 8/19/09 2899 njensen Rewrote equals() for performance * 5/08/12 #600 dgilling Implement clone(). * 6/25/12 #766 dgilling Fix isValid(). + * 01/18/13 #1504 randerso Removed setters since class should be immutable * * * @@ -487,42 +488,6 @@ public class DatabaseID implements Serializable, Comparable, return date; } - public void setSiteId(String siteId) { - this.siteId = siteId; - } - - public void setFormat(DataType format) { - this.format = format; - } - - public void setFormat(String format) { - if (format.equals("GRID")) { - this.format = DataType.GRID; - } else { - this.format = DataType.NONE; - } - } - - public void setDbType(String dbType) { - this.dbType = dbType; - } - - public void setModelName(String modelName) { - this.modelName = modelName; - } - - public void setModelTime(String modelTime) { - this.modelTime = modelTime; - } - - public void setModelId(String modelId) { - this.modelId = modelId.intern(); - } - - public void setShortModelId(String shortModelId) { - this.shortModelId = shortModelId; - } - public Date getModelTimeAsDate() { if (this.modelTime.equals(NO_MODEL_TIME)) { return new Date(0); diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.java b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.java index 5ad9ff1aeb..e8503c2226 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.java @@ -47,6 +47,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdap * ------------ ---------- ----------- -------------------------- * 3/6/08 875 bphillip Initial Creation * 5/8/12 #600 dgilling Implement clone(). + * 01/18/13 #1504 randerso Removed setters since class should be immutable * * * @@ -95,12 +96,7 @@ public class ParmID implements Comparable, Serializable, @Override public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(parmName).append("_"); - buffer.append(parmLevel).append(":"); - buffer.append(dbId.toString()); - - return buffer.toString(); + return this.parmId; } /* @@ -140,7 +136,6 @@ public class ParmID implements Comparable, Serializable, this.parmName = parmName; this.parmLevel = defaultLevel(); this.dbId = new DatabaseID(parmModel); - this.compositeName = parmName + "_" + defaultLevel(); encodeIdentifier(); } @@ -158,7 +153,6 @@ public class ParmID implements Comparable, Serializable, this.parmName = parmName; this.parmLevel = level; this.dbId = new DatabaseID(parmModel); - this.compositeName = parmName + "_" + level; encodeIdentifier(); } @@ -170,7 +164,6 @@ public class ParmID implements Comparable, Serializable, */ public ParmID(String parmIdentifier) { decodeIdentifier(parmIdentifier); - this.compositeName = this.parmName + "_" + this.parmLevel; encodeIdentifier(); } @@ -186,7 +179,6 @@ public class ParmID implements Comparable, Serializable, this.parmName = parmName; this.parmLevel = defaultLevel(); this.dbId = dbId; - this.compositeName = parmName + "_" + defaultLevel(); encodeIdentifier(); } @@ -204,7 +196,6 @@ public class ParmID implements Comparable, Serializable, this.parmName = parmName; this.parmLevel = level; this.dbId = dbId; - this.compositeName = parmName + "_" + level; encodeIdentifier(); } @@ -333,11 +324,9 @@ public class ParmID implements Comparable, Serializable, */ private void encodeIdentifier() { + this.compositeName = this.parmName + "_" + this.parmLevel; shortParmId = this.compositeName + ":" + dbId.getShortModelId(); - - if (parmId == null || parmId.length() == 0) { - parmId = this.compositeName + ":" + dbId.getModelId(); - } + parmId = this.compositeName + ":" + dbId.getModelId(); } /** @@ -442,30 +431,6 @@ public class ParmID implements Comparable, Serializable, return true; } - public void setParmName(String parmName) { - this.parmName = parmName; - } - - public void setParmLevel(String parmLevel) { - this.parmLevel = parmLevel; - } - - public void setDbId(DatabaseID dbId) { - this.dbId = dbId; - } - - public void setCompositeName(String compositeName) { - this.compositeName = compositeName; - } - - public void setShortParmId(String shortParmId) { - this.shortParmId = shortParmId; - } - - public void setParmId(String parmId) { - this.parmId = parmId; - } - /* * (non-Javadoc) * diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java index faf88b060d..d52333e894 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java @@ -44,6 +44,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; /** @@ -61,7 +62,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; * Apr 11, 2012 #14691 Qinglu Lin For marine warnings, getFeAreaField() returns null. * So, do not add the returned value of getFeAreaField() * to areaFields. - * Jan 9, 2013 15600 Qinglu Lin Execute "timezones = myTimeZones;" even if timezones != null. + * Jan 9, 2013 15600 Qinglu Lin Execute "timezones = myTimeZones;" even if timezones != null. * * * @@ -87,13 +88,12 @@ public class GeospatialFactory { boolean generate = true; if (lastRunTime != null) { System.out.println("Loading areas from disk"); - // load from disk try { long t0 = System.currentTimeMillis(); dataSet = loadAreaGeoData(site, lastRunTime); System.out.println("Loading areas from disk took " - + (System.currentTimeMillis() - t0)); + + (System.currentTimeMillis() - t0) + "ms"); } catch (Exception e) { statusHandler.handle(Priority.WARN, "Failed to load area geometry files from disk", e); @@ -119,7 +119,7 @@ public class GeospatialFactory { GeospatialData[] parentAreas = dataSet.getParentAreas(); GeospatialData[] myTimeZones = dataSet.getTimezones(); if (myTimeZones != null && myTimeZones.length > 0) { - timezones = myTimeZones; + timezones = myTimeZones; for (GeospatialData tz : myTimeZones) { tz.prepGeom = PreparedGeometryFactory.prepare(tz.geometry); @@ -138,7 +138,6 @@ public class GeospatialFactory { list.add(data); } - GeospatialData[] uniqueAreas = new GeospatialData[uniqueAreasMap.size()]; int index = 0; for (String key : uniqueAreasMap.keySet()) { @@ -148,34 +147,15 @@ public class GeospatialFactory { // if multiple areas share a common fips ID, the smaller areas will // have to merge will the largest area if (list.size() > 1) { - double maxArea = -1; - for (GeospatialData item : list) { - double area = item.getGeometry().getArea(); - if (area > maxArea) { - data = item; - maxArea = area; - } - } - - // collect all individual geometries that are not a part - // of the maxArea + // collect all individual geometries List geometries = new ArrayList(); for (GeospatialData item : list) { - if (data != item) { - GeometryUtil.buildGeometryList(geometries, - item.geometry); - } - } - - for (int i = 0; i < geometries.size(); i++) { - // convexHull will remove any side location conflicts - // convexHull the geometries individually because they are - // usually not next to each other. - // data.geometry = data.geometry.union(geometries.get(i) - // .convexHull()); - data.geometry = data.geometry.union(geometries.get(i) - .convexHull()); + GeometryUtil.buildGeometryList(geometries, item.geometry); } + // Create multi geometry out of combined areas + data.geometry = new GeometryFactory() + .createGeometryCollection(geometries + .toArray(new Geometry[0])); } uniqueAreas[index] = data; index++; @@ -204,7 +184,7 @@ public class GeospatialFactory { // Prepare the geometries for (GeospatialData data : areas) { - data.prepGeom = PreparedGeometryFactory.prepare(data.geometry); + data.prepGeom = new PreparedGeometryCollection(data.geometry); } return areas; diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/PreparedGeometryCollection.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/PreparedGeometryCollection.java new file mode 100644 index 0000000000..8b6188438e --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/PreparedGeometryCollection.java @@ -0,0 +1,246 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.dataplugin.warning.gis; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryCollection; +import com.vividsolutions.jts.geom.prep.PreparedGeometry; +import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; + +/** + * {@link PreparedGeometry} implementation that can handle + * {@link GeometryCollection} objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 28, 2013            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class PreparedGeometryCollection implements PreparedGeometry { + + private Geometry geometry; + + private PreparedGeometry[] prepared; + + public PreparedGeometryCollection(Geometry geometry) { + this.geometry = geometry; + int numGeoms = geometry.getNumGeometries(); + if (geometry.getClass() == GeometryCollection.class) { + prepared = new PreparedGeometry[numGeoms]; + for (int i = 0; i < numGeoms; ++i) { + prepared[i] = PreparedGeometryFactory.prepare(geometry + .getGeometryN(i)); + } + } else { + prepared = new PreparedGeometry[] { PreparedGeometryFactory + .prepare(geometry) }; + } + } + + /* + * (non-Javadoc) + * + * @see com.vividsolutions.jts.geom.prep.PreparedGeometry#getGeometry() + */ + @Override + public Geometry getGeometry() { + return geometry; + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#contains(com.vividsolutions + * .jts.geom.Geometry) + */ + @Override + public boolean contains(Geometry geom) { + for (PreparedGeometry pg : prepared) { + if (pg.contains(geom)) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#containsProperly(com + * .vividsolutions.jts.geom.Geometry) + */ + @Override + public boolean containsProperly(Geometry geom) { + for (PreparedGeometry pg : prepared) { + if (pg.containsProperly(geom)) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see com.vividsolutions.jts.geom.prep.PreparedGeometry#coveredBy(com. + * vividsolutions.jts.geom.Geometry) + */ + @Override + public boolean coveredBy(Geometry geom) { + boolean coveredBy = true; + for (PreparedGeometry pg : prepared) { + if (pg.coveredBy(geom) == false) { + coveredBy = false; + break; + } + } + return coveredBy; + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#covers(com.vividsolutions + * .jts.geom.Geometry) + */ + @Override + public boolean covers(Geometry geom) { + throw new UnsupportedOperationException( + "PreparedGeometryCollection does not support PreparedGeometry.covers"); + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#crosses(com.vividsolutions + * .jts.geom.Geometry) + */ + @Override + public boolean crosses(Geometry geom) { + for (PreparedGeometry pg : prepared) { + if (pg.crosses(geom)) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#disjoint(com.vividsolutions + * .jts.geom.Geometry) + */ + @Override + public boolean disjoint(Geometry geom) { + boolean disjoint = true; + for (PreparedGeometry pg : prepared) { + if (pg.disjoint(geom) == false) { + disjoint = false; + break; + } + } + return disjoint; + } + + /* + * (non-Javadoc) + * + * @see com.vividsolutions.jts.geom.prep.PreparedGeometry#intersects(com. + * vividsolutions.jts.geom.Geometry) + */ + @Override + public boolean intersects(Geometry geom) { + for (PreparedGeometry pg : prepared) { + if (pg.intersects(geom)) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#overlaps(com.vividsolutions + * .jts.geom.Geometry) + */ + @Override + public boolean overlaps(Geometry geom) { + for (PreparedGeometry pg : prepared) { + if (pg.overlaps(geom)) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#touches(com.vividsolutions + * .jts.geom.Geometry) + */ + @Override + public boolean touches(Geometry geom) { + for (PreparedGeometry pg : prepared) { + if (pg.touches(geom)) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.vividsolutions.jts.geom.prep.PreparedGeometry#within(com.vividsolutions + * .jts.geom.Geometry) + */ + @Override + public boolean within(Geometry geom) { + boolean within = true; + for (PreparedGeometry pg : prepared) { + if (pg.within(geom) == false) { + within = false; + break; + } + } + return within; + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/util/GeometryUtil.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/util/GeometryUtil.java index 0ce2c7f5f2..a3765c3876 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/util/GeometryUtil.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/util/GeometryUtil.java @@ -1,24 +1,38 @@ package com.raytheon.uf.common.dataplugin.warning.util; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; -import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; -import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Polygon; -import com.vividsolutions.jts.geom.TopologyException; import com.vividsolutions.jts.geom.prep.PreparedGeometry; import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; import com.vividsolutions.jts.operation.overlay.snap.GeometrySnapper; -import com.vividsolutions.jts.operation.polygonize.Polygonizer; +/** + * + * Performs common geometry operations taking geometry collections into + * account for counties. Makes certain assumptions about these geometries that + * only apply to warngen + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 15, 2010            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ public class GeometryUtil { private static final String SEPARATOR = "_"; @@ -41,7 +55,7 @@ public class GeometryUtil { } for (int i = 0; i < list1.size(); ++i) { - if (list1.get(i).buffer(0).equals(list2.get(i).buffer(0)) == false) { + if (list1.get(i).equals(list2.get(i)) == false) { return false; } } @@ -190,12 +204,15 @@ public class GeometryUtil { } if ((g1Name == null || g2Name == null || g2Name .startsWith(prefix))) { - Geometry section = g1.intersection(g2); - if (section.isEmpty() == false) { - section = section.buffer(0); - setUserData(section, (CountyUserData) g2.getUserData()); - section.setUserData(g2.getUserData()); - intersections.add(section); + if (g1.isValid() && g2.isValid()) { + Geometry section = g1.intersection(g2); + if (section.isEmpty() == false) { + section = section.buffer(0); + setUserData(section, + (CountyUserData) g2.getUserData()); + section.setUserData(g2.getUserData()); + intersections.add(section); + } } } } @@ -209,64 +226,31 @@ public class GeometryUtil { intersection(g1.getGeometryN(i), pg, intersections); } } else { - Geometry g2 = pg.getGeometry(); - String g1Name = toString(g1.getUserData()); - String g2Name = toString(g2.getUserData()); - String prefix = null; - if (g1Name != null && g2Name != null) { - prefix = getPrefix(g1Name); - } - if (g1Name == null || g2Name == null || g2Name.startsWith(prefix)) { - if (pg.intersects(g1)) { - Geometry section = null; - try { - section = g1.intersection(g2); - } catch (TopologyException e) { - // This exception is due to g2 having interior - // intersections - section = clean(g1).intersection(g2.buffer(0)); - } - - if (section != null) { - setUserData(section, (CountyUserData) g2.getUserData()); - section.setUserData(g2.getUserData()); - intersections.add(section); + if (pg.intersects(g1)) { + Geometry g2 = pg.getGeometry(); + List sections = new ArrayList(); + for (int n = 0; n < g2.getNumGeometries(); n++) { + Geometry section = g1.intersection(g2.getGeometryN(n)); + if (section.isEmpty() == false) { + sections.add(section); } } + Geometry section = null; + if (sections.size() == 1) { + section = sections.get(0); + } else if (sections.size() > 0) { + section = new GeometryFactory() + .createGeometryCollection(sections + .toArray(new Geometry[0])); + } + if (section != null && section.isEmpty() == false) { + setUserData(section, (CountyUserData) g2.getUserData()); + intersections.add(section); + } } } } - /** - * Returns a geometry from the noded line strings of g. - * - * @param g - * geometry to be cleaned up - * @return - */ - private static Geometry clean(Geometry g) { - Coordinate[] coords = g.getCoordinates(); - - // create a line string - GeometryFactory gf = new GeometryFactory(); - LineString ls = gf.createLineString(coords); - - // node the line string (insert vertices where lines cross) - com.vividsolutions.jts.geom.Point pt = gf.createPoint(ls - .getCoordinate()); - Geometry nodedLines = ls.union(pt); - - // create the polygon(s) from the noded line - Polygonizer polygonizer = new Polygonizer(); - polygonizer.add(nodedLines); - Collection polygons = polygonizer.getPolygons(); - - g = gf.createMultiPolygon( - polygons.toArray(new Polygon[polygons.size()])).buffer(0); - - return g; - } - /** * Get the difference between the 2 geometries * diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java index 8d60a25624..62fcae6ef6 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java @@ -19,6 +19,8 @@ **/ package com.raytheon.uf.common.dataquery.responses; +import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -47,15 +49,31 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @DynamicSerialize public class DbQueryResponse implements ISerializableObject { + public static final String ENTITY_RESULT_KEY = null; + @DynamicSerializeElement private List> results; public List> getResults() { - return results; + return results == null ? new ArrayList>() : results; } public void setResults(List> results) { this.results = results; } + public int getNumResults() { + return getResults().size(); + } + + @SuppressWarnings("unchecked") + public T[] getEntityObjects(Class entityType) { + List> results = getResults(); + T[] entities = (T[]) Array.newInstance(entityType, results.size()); + int i = 0; + for (Map result : results) { + entities[i++] = entityType.cast(result.get(ENTITY_RESULT_KEY)); + } + return entities; + } } diff --git a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java index 811ccdc6f1..08b78508a8 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java +++ b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java @@ -29,6 +29,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import javax.xml.bind.JAXBException; + import com.raytheon.uf.common.localization.FileLocker.Type; import com.raytheon.uf.common.localization.ILocalizationAdapter.ListResponse; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; @@ -80,6 +82,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * This was added as part of an effort to improve * localization performance but caused updated * files on the server not to be retrieved. + * Jan 17, 2013 1412 djohnson Add jaxbMarshal. * * * @author njensen @@ -635,6 +638,25 @@ public final class LocalizationFile implements Comparable { return null; } + /** + * Marshal the specified object into this file. + * + * @param obj + * the object to marshal + * + * @param jaxbManager + * the jaxbManager + */ + public void jaxbMarshal(Object obj, JAXBManager jaxbManager) throws LocalizationException{ + try { + String xml = jaxbManager.marshalToXml(obj); + write(xml.getBytes()); + } catch (JAXBException e) { + throw new LocalizationException( + "Unable to marshal the object to the file.", e); + } + } + @Override public String toString() { return context + IPathManager.SEPARATOR + path; diff --git a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/META-INF/MANIFEST.MF index 76e9413bb9..57095e23d0 100644 --- a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/META-INF/MANIFEST.MF @@ -10,7 +10,8 @@ Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.12.2", com.raytheon.uf.common.auth;bundle-version="1.12.1174", com.raytheon.uf.common.status;bundle-version="1.12.1174", com.raytheon.uf.common.localization;bundle-version="1.12.1174", - com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174" + com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174", + org.apache.commons.lang;bundle-version="2.3.0" Export-Package: com.raytheon.uf.common.plugin.nwsauth, com.raytheon.uf.common.plugin.nwsauth.exception, com.raytheon.uf.common.plugin.nwsauth.user, diff --git a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/NwsRoleData.java b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/NwsRoleData.java index 6dd1df05b6..8194b50017 100644 --- a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/NwsRoleData.java +++ b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/NwsRoleData.java @@ -302,4 +302,21 @@ public class NwsRoleData implements ISerializableObject { return false; } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Application:").append(this.getApplication()).append("\n\n"); + sb.append("Users:\n").append(this.getUserList()).append("\n\n"); + sb.append("Permissions:\n").append(this.getPermissionList()) + .append("\n\n"); + sb.append("Roles:\n").append(this.getRoleList()).append("\n\n"); + + return sb.toString(); + } } diff --git a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/PermissionXML.java b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/PermissionXML.java index 824f9af8de..1966f492ea 100644 --- a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/PermissionXML.java +++ b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/PermissionXML.java @@ -94,4 +94,16 @@ public class PermissionXML implements ISerializableObject { public void setDescription(String description) { this.description = (description == null) ? null : description.trim(); } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("id:").append(this.getId()); + sb.append("\ndescription:").append(this.getDescription()); + + return sb.toString(); + } } diff --git a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/RoleXML.java b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/RoleXML.java index d17db43ea3..5802aa8118 100644 --- a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/RoleXML.java +++ b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/RoleXML.java @@ -117,4 +117,19 @@ public class RoleXML implements ISerializableObject { public void addPermission(String permission) { this.permissionList.add(permission); } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("roleId:").append(this.getRoleId()); + sb.append("\nroleDescription:").append(this.getRoleDescription()); + sb.append("\npermissionList:").append(this.getPermissionList()); + + return sb.toString(); + } } diff --git a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/UserXML.java b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/UserXML.java index aa8089901e..61f9a5d19e 100644 --- a/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/UserXML.java +++ b/edexOsgi/com.raytheon.uf.common.plugin.nwsauth/src/com/raytheon/uf/common/plugin/nwsauth/xml/UserXML.java @@ -28,6 +28,9 @@ import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElements; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + import com.raytheon.uf.common.auth.user.IAuthenticationData; import com.raytheon.uf.common.auth.user.IUser; import com.raytheon.uf.common.auth.user.IUserId; @@ -66,6 +69,17 @@ public class UserXML implements IUser, ISerializableObject { @XmlElements({ @XmlElement(name = "userRole", type = String.class) }) private List roleList = new ArrayList(); + public UserXML() { + + } + + /** + * @param userId + */ + public UserXML(String userId) { + setUserId(userId); + } + /** * @return the userId */ @@ -129,6 +143,30 @@ public class UserXML implements IUser, ISerializableObject { } } + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof UserXML) { + UserXML that = (UserXML) obj; + + EqualsBuilder builder = new EqualsBuilder(); + builder.append(this.getUserId(), that.getUserId()); + return builder.isEquals(); + + } + return super.equals(obj); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder().append(this.getUserId()).toHashCode(); + } + /* * (non-Javadoc) * @@ -136,17 +174,10 @@ public class UserXML implements IUser, ISerializableObject { */ @Override public String toString() { - final String nl = "\n"; StringBuilder sb = new StringBuilder(); - sb.append(this.getUserId()).append(nl); - - for (String role : this.roleList) { - sb.append(" ").append(role).append(nl); - } - - for (String perm : permissionList) { - sb.append(" ").append(perm).append(nl); - } + sb.append("userId:").append(this.getUserId()); + sb.append("\nroles:").append(this.getRoleList()); + sb.append("\npermissions:").append(this.getPermissionList()); return sb.toString(); } diff --git a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/ExtensibleObjectType.java b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/ExtensibleObjectType.java index 85ed507ab1..4907aeac36 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/ExtensibleObjectType.java +++ b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/ExtensibleObjectType.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; @@ -39,6 +40,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryExceptionType; import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryRequestType; import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryResponseType; +import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @@ -82,10 +84,11 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; RegistryResponseType.class, RegistryRequestType.class }) @DynamicSerialize @MappedSuperclass -@Cache(region="registryObjects",usage = CacheConcurrencyStrategy.TRANSACTIONAL, include = "all") +@Cache(region = "registryObjects", usage = CacheConcurrencyStrategy.TRANSACTIONAL, include = "all") public abstract class ExtensibleObjectType { - @ManyToMany(cascade = CascadeType.ALL) + @BatchSize(size = 500) + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinTable(inverseJoinColumns = @JoinColumn(name = "child_slot_key")) @XmlElement(name = "Slot") @DynamicSerializeElement diff --git a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/RegistryObjectType.java b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/RegistryObjectType.java index ddffcce84f..5e566b091f 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/RegistryObjectType.java +++ b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/RegistryObjectType.java @@ -100,45 +100,45 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; RoleType.class }) @DynamicSerialize @Entity -@Cache(region="registryObjects",usage = CacheConcurrencyStrategy.TRANSACTIONAL, include = "all") +@Cache(region = "registryObjects", usage = CacheConcurrencyStrategy.TRANSACTIONAL, include = "all") @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Table(name = "RegistryObject") public class RegistryObjectType extends IdentifiableType { @XmlElement(name = "Name") @DynamicSerializeElement - @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) protected InternationalStringType name; @XmlElement(name = "Description") @DynamicSerializeElement - @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) protected InternationalStringType description; @XmlElement(name = "VersionInfo") @DynamicSerializeElement @Cascade(value = { org.hibernate.annotations.CascadeType.DETACH }) - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) protected VersionInfoType versionInfo; @XmlElement(name = "Classification") @DynamicSerializeElement @Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DETACH }) - @ManyToMany + @ManyToMany(fetch = FetchType.LAZY) protected Set classification; @XmlElement(name = "ExternalIdentifier") @DynamicSerializeElement @Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DETACH }) - @ManyToMany + @ManyToMany(fetch = FetchType.LAZY) protected Set externalIdentifier; @XmlElement(name = "ExternalLink") @DynamicSerializeElement @Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DETACH }) - @ManyToMany + @ManyToMany(fetch = FetchType.LAZY) protected Set externalLink; @XmlAttribute diff --git a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/SlotType.java b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/SlotType.java index b006e5d63b..b3416a82e8 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/SlotType.java +++ b/edexOsgi/com.raytheon.uf.common.registry.schemas.ebxml/src/oasis/names/tc/ebxml/regrep/xsd/rim/v4/SlotType.java @@ -24,6 +24,7 @@ import java.io.Serializable; import javax.persistence.CascadeType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; @@ -83,7 +84,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; // "slot_join_slot", joinColumns = @JoinColumn(name = "parent_slot_key", // referencedColumnName = "key"), inverseJoinColumns = @JoinColumn(name = // "child_slot_key", referencedColumnName = "key"))) -@Cache(region="registryObjects",usage = CacheConcurrencyStrategy.TRANSACTIONAL, include = "all") +@Cache(region = "registryObjects", usage = CacheConcurrencyStrategy.TRANSACTIONAL, include = "all") @Table(name = "Slot") public class SlotType extends ExtensibleObjectType implements Serializable { @@ -94,7 +95,7 @@ public class SlotType extends ExtensibleObjectType implements Serializable { @XmlTransient private Integer key; - @ManyToOne(cascade = CascadeType.ALL) + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @XmlElement(name = "SlotValue") @DynamicSerializeElement protected ValueType slotValue; diff --git a/edexOsgi/com.raytheon.uf.common.stats/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.stats/META-INF/MANIFEST.MF index 81c3d897a6..3ecb4c506e 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.stats/META-INF/MANIFEST.MF @@ -17,4 +17,6 @@ Require-Bundle: com.raytheon.uf.common.time;bundle-version="1.12.1174", com.raytheon.uf.common.event;bundle-version="1.0.0", com.google.guava;bundle-version="1.0.0", com.raytheon.uf.common.util;bundle-version="1.12.1174", - com.raytheon.uf.common.status;bundle-version="1.12.1174" + com.raytheon.uf.common.status;bundle-version="1.12.1174", + javax.measure;bundle-version="1.0.0", + com.raytheon.uf.common.units;bundle-version="1.0.0" diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/AggregateRecord.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/AggregateRecord.java index fba2d6127d..9ffbc05a71 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/AggregateRecord.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/AggregateRecord.java @@ -37,17 +37,18 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** * Record class for an aggregate result. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Aug 21, 2012            jsanchez     Initial creation
  * Nov 12, 2012            dhladky      Updates some things for stats
- *
+ * Jan 15, 2013 1487       djohnson     Increase length of grouping to 1024.
+ * 
  * 
- * + * * @author jsanchez * @version 1.0 */ @@ -56,7 +57,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize -public class AggregateRecord extends PersistableDataObject { +public class AggregateRecord extends PersistableDataObject { private static final long serialVersionUID = -4553588456131256014L; @GeneratedValue(strategy = GenerationType.AUTO) @@ -77,6 +78,7 @@ public class AggregateRecord extends PersistableDataObject { private String eventType; @DynamicSerializeElement + @Column(length = 1024) private String grouping; @Column(nullable = false) diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/GraphDataRequest.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/GraphDataRequest.java index 340fb9ff9b..0803581c90 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/GraphDataRequest.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/GraphDataRequest.java @@ -36,6 +36,7 @@ import com.raytheon.uf.common.time.TimeRange; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 11, 2012 728 mpduff Initial creation + * Jan 17, 2013 1357 mpudff Javadoc update. * * * @@ -139,6 +140,8 @@ public class GraphDataRequest implements IServerRequest { } /** + * The time step of the data in minutes. + * * @param timeStep * the timeStep to set */ @@ -147,6 +150,8 @@ public class GraphDataRequest implements IServerRequest { } /** + * Get the time step in minute. + * * @return the timeStep */ public int getTimeStep() { diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/StatsGrouping.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/StatsGrouping.java new file mode 100644 index 0000000000..3995883cbc --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/StatsGrouping.java @@ -0,0 +1,101 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.stats; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * Contains a grouping for statistics. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 15, 2013 1487       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +public class StatsGrouping { + + @XmlAttribute(required = true) + private String name; + + @XmlAttribute(required = true) + private String value; + + /** + * Constructor. + */ + public StatsGrouping() { + this(null, null); + } + + /** + * Constructor. + * + * @param name + * @param value + */ + public StatsGrouping(String name, String value) { + this.name = name; + this.value = value; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value + * the value to set + */ + public void setValue(String value) { + this.value = value; + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/StatsGroupingColumn.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/StatsGroupingColumn.java new file mode 100644 index 0000000000..b63902407a --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/StatsGroupingColumn.java @@ -0,0 +1,87 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.stats; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.google.common.collect.Lists; + +/** + * Contains a list of groupings for statistics. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 15, 2013 1487       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlRootElement(name = "stat") +@XmlAccessorType(XmlAccessType.NONE) +public class StatsGroupingColumn { + + @XmlElement + private List group = Lists.newArrayList(); + + /** + * @return the group + */ + public List getGroup() { + return group; + } + + /** + * @param group + * the group to set + */ + public void setGroup(List group) { + this.group = group; + } + + /** + * Create a {@link StatsGroupingColumn} to hold the specified + * {@link StatsGrouping} instances. + * + * @param statsGroupings + * the groupings + * @return the column + */ + public static StatsGroupingColumn withGroupings( + StatsGrouping... statsGroupings) { + StatsGroupingColumn column = new StatsGroupingColumn(); + + for (StatsGrouping grouping : statsGroupings) { + column.group.add(grouping); + } + + return column; + } +} diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/DataPoint.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/DataPoint.java index 569bd719cd..4173991538 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/DataPoint.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/DataPoint.java @@ -20,10 +20,6 @@ package com.raytheon.uf.common.stats.data; import java.math.BigDecimal; -import java.text.DecimalFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -31,7 +27,8 @@ import javax.xml.bind.annotation.XmlRootElement; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; -import com.raytheon.uf.common.stats.util.DataViewUtils; +import com.raytheon.uf.common.stats.util.DataView; +import com.raytheon.uf.common.stats.util.UnitUtils.UnitTypes; /** * Class holding an x,y data point and other associated information for the @@ -43,7 +40,8 @@ import com.raytheon.uf.common.stats.util.DataViewUtils; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Sep 7, 2012 mpduff Initial creation + * Sep 7, 2012 mpduff Initial creation + * Jan 17, 2013 1357 mpduff Moved sample code out of this class. * * * @@ -55,37 +53,12 @@ import com.raytheon.uf.common.stats.util.DataViewUtils; @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class DataPoint implements Comparable { - /** Date Format object */ - private final ThreadLocal sdf = new ThreadLocal() { - @Override - protected SimpleDateFormat initialValue() { - SimpleDateFormat sTemp = new SimpleDateFormat("MM/dd/yyyy HH:mm"); - sTemp.setTimeZone(TimeZone.getTimeZone("GMT")); - return sTemp; - } - }; - - /** Decimal Format object */ - private final ThreadLocal decFormat = new ThreadLocal() { - @Override - protected DecimalFormat initialValue() { - DecimalFormat format = new DecimalFormat("########.#"); - return format; - } - }; - /** * X value - millis */ @DynamicSerializeElement private long x; - /** - * Text display for the sampling of this point - */ - @DynamicSerializeElement - protected String sampleText; - /** Min value */ @DynamicSerializeElement private BigDecimal min = new BigDecimal(Integer.MAX_VALUE); @@ -102,6 +75,9 @@ public class DataPoint implements Comparable { @DynamicSerializeElement private BigDecimal sum = new BigDecimal(0); + @DynamicSerializeElement + private UnitTypes unitType; + /** Constructor */ public DataPoint() { sum = sum.setScale(1, BigDecimal.ROUND_HALF_UP); @@ -110,27 +86,6 @@ public class DataPoint implements Comparable { count = count.setScale(1, BigDecimal.ROUND_HALF_UP); } - /** - * @param sampleText - * the sampleText to set - */ - public void setSampleText(String sampleText) { - this.sampleText = sampleText; - } - - /** - * Get the sample text for this point object - * - * @return the sample text string - */ - public String getSampleText(String view) { - SimpleDateFormat dateFormat = sdf.get(); - DecimalFormat decimalFormat = decFormat.get(); - - return dateFormat.format(new Date(x)) + "Z, " - + decimalFormat.format(getValue(view)); - } - /** * @param x * the x to set @@ -258,20 +213,35 @@ public class DataPoint implements Comparable { return 0; } + /** + * @return the unitType + */ + public UnitTypes getUnitType() { + return unitType; + } + + /** + * @param unitType + * the unitType to set + */ + public void setUnitType(UnitTypes unitType) { + this.unitType = unitType; + } + /** * Get the value for the provided data view type. * * @param view * the view type */ - public double getValue(String view) { - if (view.equals(DataViewUtils.DataView.AVG.getView())) { + public double getValue(DataView view) { + if (view.equals(DataView.AVG)) { return getAvg(); - } else if (view.equals(DataViewUtils.DataView.MIN.getView())) { + } else if (view.equals(DataView.MIN)) { return getMin(); - } else if (view.equals(DataViewUtils.DataView.MAX.getView())) { + } else if (view.equals(DataView.MAX)) { return getMax(); - } else if (view.equals(DataViewUtils.DataView.SUM.getView())) { + } else if (view.equals(DataView.SUM)) { return getSum(); } else { return getCount(); diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/GraphData.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/GraphData.java index c05481534f..9e13e54f5a 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/GraphData.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/GraphData.java @@ -33,7 +33,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.raytheon.uf.common.stats.AggregateRecord; import com.raytheon.uf.common.stats.StatisticsEvent; -import com.raytheon.uf.common.stats.util.UnitUtils; +import com.raytheon.uf.common.stats.util.DataView; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -43,17 +43,18 @@ import com.raytheon.uf.common.util.ReflectionUtil; /** * Data object for the statistics graph. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Oct 3, 2012     728     mpduff      Initial creation
- *
+ * Oct 03, 2012    728     mpduff      Initial creation
+ * Jan 17, 2013   1357     mpduff      Add timestep.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -96,8 +97,17 @@ public class GraphData { @DynamicSerializeElement private String displayUnit; - /** UnitUtils object */ - private UnitUtils unitUtils; + /** Timestep value */ + @DynamicSerializeElement + private long timeStep; + + /** Event Type value */ + @DynamicSerializeElement + private String eventType; + + /** Data Type value */ + @DynamicSerializeElement + private String dataType; /** * Constructor. @@ -130,7 +140,7 @@ public class GraphData { /** * Add an AggregateRecord. - * + * * @param record */ public void addRecord(AggregateRecord record) { @@ -148,7 +158,7 @@ public class GraphData { /** * Get a list of group memebers. - * + * * @return */ public List getGroupMembers() { @@ -160,7 +170,7 @@ public class GraphData { /** * Get the smallest value in the data set. - * + * * @return */ public double getMinValue() { @@ -177,7 +187,7 @@ public class GraphData { /** * Get the largest value in the data set. - * + * * @return */ public double getMaxValue() { @@ -194,10 +204,10 @@ public class GraphData { /** * Get the smallest value in the data set. - * + * * @return */ - public double getMinValue(Set visibleDataSet, String view) { + public double getMinValue(Set visibleDataSet, DataView view) { if (visibleDataSet.isEmpty()) { return 0; } @@ -217,10 +227,10 @@ public class GraphData { /** * Get the largest value in the data set. - * + * * @return */ - public double getMaxValue(Set visibleDataSet, String view) { + public double getMaxValue(Set visibleDataSet, DataView view) { if (visibleDataSet.isEmpty()) { return 1; } @@ -239,7 +249,7 @@ public class GraphData { /** * Get the time range for this object. - * + * * @return */ public TimeRange getTimeRange() { @@ -248,7 +258,7 @@ public class GraphData { /** * Set the TimeRange - * + * * @param timeRange */ public void setTimeRange(TimeRange timeRange) { @@ -257,7 +267,7 @@ public class GraphData { /** * Set the key sequence - * + * * @param keySequence */ public void setKeySequence(List keySequence) { @@ -270,7 +280,7 @@ public class GraphData { /** * Get the key sequence. - * + * * @return */ public List getKeySequence() { @@ -279,7 +289,7 @@ public class GraphData { /** * Get a list of all keys. - * + * * @return the keys */ public List getKeys() { @@ -288,7 +298,7 @@ public class GraphData { /** * Get a list of keys that contain data. - * + * * @return the keys with data */ public List getKeysWithData() { @@ -305,7 +315,7 @@ public class GraphData { /** * Set the StatsLabelData object - * + * * @param statsLabelData */ public void setStatsLabelData(StatsLabelData statsLabelData) { @@ -315,7 +325,7 @@ public class GraphData { /** * Get the StatsLabelData - * + * * @return */ public StatsLabelData getStatsLabelData() { @@ -324,7 +334,7 @@ public class GraphData { /** * Get the group and names map. - * + * * @return */ public Map> getGroupAndNamesMap() { @@ -333,12 +343,12 @@ public class GraphData { /** * Get the units from the event object - * + * * @param eventId * Event id * @param field * data field - * + * * @return The units */ @VisibleForTesting @@ -397,7 +407,7 @@ public class GraphData { /** * Set the StatsData map. - * + * * @param statsDataMap */ public void setStatsDataMap(Map statsDataMap) { @@ -405,18 +415,47 @@ public class GraphData { } /** - * @return the unitUtils + * @return the timeStep */ - public UnitUtils getUnitUtils() { - return unitUtils; + public long getTimeStep() { + return timeStep; } /** - * @param unitUtils - * the unitUtils to set + * @param timeStep + * the timeStep to set */ - public void setUnitUtils(UnitUtils unitUtils) { - this.unitUtils = unitUtils; - this.unitUtils.setConversion(this.getMaxValue()); + public void setTimeStep(long timeStep) { + this.timeStep = timeStep; + } + + /** + * @return the eventType + */ + public String getEventType() { + return eventType; + } + + /** + * @param eventType + * the eventType to set + */ + public void setEventType(String eventType) { + this.eventType = eventType; + } + + /** + * @return the dataType + */ + public String getDataType() { + return dataType; + } + + /** + * @param dataType + * the dataType to set + */ + public void setDataType(String dataType) { + this.dataType = dataType; } } diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsBin.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsBin.java index b06266cf9f..5174931dd4 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsBin.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsBin.java @@ -28,17 +28,18 @@ import com.raytheon.uf.common.stats.AggregateRecord; /** * A bin of Statistical data. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Sep 11, 2012   723      mpduff      Initial creation
- *
+ * Sep 11, 2012   723      mpduff      Initial creation.
+ * Jan 17, 2013  1357      mpduff      Change method name.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -57,6 +58,17 @@ public class StatsBin { } + /** + * Copy constructor. + * + * @param bin + * The StatsBin object to copy + */ + public StatsBin(StatsBin bin) { + this.setBinMillis(bin.getBinMillis()); + data.addAll(bin.getData()); + } + /** * @return the binMillis */ @@ -74,16 +86,16 @@ public class StatsBin { /** * Add an AggregateRecord object. - * + * * @param record */ - public void setData(AggregateRecord record) { + public void addData(AggregateRecord record) { this.data.add(record); } /** * Get the AggregateRecord objects - * + * * @return */ public List getData() { diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsData.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsData.java index 2b4dc162ff..5481057de8 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsData.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsData.java @@ -32,22 +32,23 @@ import javax.xml.bind.annotation.XmlRootElement; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.raytheon.uf.common.stats.AggregateRecord; -import com.raytheon.uf.common.stats.util.UnitUtils; +import com.raytheon.uf.common.stats.util.DataView; import com.raytheon.uf.common.time.TimeRange; /** * Statistical data object holding data to be graphed. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Sep 07, 2012    728     mpduff      Initial creation
- *
+ * Sep 07, 2012    728     mpduff      Initial creation.
+ * Jan 17, 2013   1357     mpduff      Store data in raw units, not converted.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -84,9 +85,6 @@ public class StatsData { @DynamicSerializeElement private Map bins; - /** UnitUtils object */ - private UnitUtils unitUtils; - /** Constructor */ public StatsData() { @@ -94,7 +92,7 @@ public class StatsData { /** * Constructor - * + * * @param key * Key to the object * @param tsMillis @@ -104,12 +102,10 @@ public class StatsData { * @param unitUtils * UnitUtils object */ - public StatsData(String key, long tsMillis, TimeRange timeRange, - UnitUtils unitUtils) { + public StatsData(String key, long tsMillis, TimeRange timeRange) { this.key = key; this.dataFrequency = (int) tsMillis; this.timeRange = timeRange; - this.unitUtils = unitUtils; } /** @@ -130,7 +126,7 @@ public class StatsData { /** * @return the minValue */ - public Double getMinValue(String view) { + public Double getMinValue(DataView view) { double minValue = Integer.MAX_VALUE; for (DataPoint point : pointList) { @@ -145,7 +141,7 @@ public class StatsData { /** * @return the minValue */ - public Double getMaxValue(String view) { + public Double getMaxValue(DataView view) { double maxValue = Integer.MIN_VALUE; for (DataPoint point : pointList) { @@ -189,7 +185,7 @@ public class StatsData { /** * Get the list of DataPoint objects for the key. - * + * * @param key * The key * @return List of DataPoint objects @@ -216,7 +212,7 @@ public class StatsData { /** * Add an AggregateRecord. - * + * * @param rec * the record to add */ @@ -226,7 +222,7 @@ public class StatsData { /** * Get the key - * + * * @return */ public String getKey() { @@ -235,7 +231,7 @@ public class StatsData { /** * Set the key - * + * * @param key * the key to set */ @@ -245,7 +241,7 @@ public class StatsData { /** * Set the StatsBin object map. - * + * * @param bins */ public void setBins(Map bins) { @@ -263,7 +259,7 @@ public class StatsData { long start = startDate.getTime(); long bin = getBinKey(start); if (bins.get(bin) != null) { - bins.get(bin).setData(record); + bins.get(bin).addData(record); } } @@ -272,13 +268,11 @@ public class StatsData { /** * Create the points for this key. - * + * * @param dataKey */ private void createPoints() { // Bins are created, now make the graph group member and point objects - // convert the data values before storing in the data object - double conversion = unitUtils.getConversion(); for (long key : bins.keySet()) { StatsBin sb = bins.get(key); List dataList = sb.getData(); @@ -288,9 +282,9 @@ public class StatsData { for (AggregateRecord rec : dataList) { // Check for an existing point object - point.setMax(rec.getMax() / conversion); - point.setMin(rec.getMin() / conversion); - point.setSum(rec.getSum() / conversion); + point.setMax(rec.getMax()); + point.setMin(rec.getMin()); + point.setSum(rec.getSum()); point.addToCount(rec.getCount()); } @@ -301,7 +295,7 @@ public class StatsData { /** * Get the bin key for the given millisecond value. - * + * * @param millis * The millisecond value * @return The bin that should hold this millisecond value diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsEventData.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsEventData.java index c7351576bd..f33f0be176 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsEventData.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/data/StatsEventData.java @@ -26,17 +26,18 @@ import java.util.Map; /** * Stats Event helper object. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Nov 8, 2012    728      mpduff      Initial creation
- *
+ * Nov 08, 2012    728     mpduff      Initial creation.
+ * Jan 23, 2013   1523     mpduff      Fix list length.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @@ -136,7 +137,7 @@ public class StatsEventData { /** * Get the group list - * + * * @return */ public String[] getGroups() { @@ -145,16 +146,16 @@ public class StatsEventData { /** * Get the attribute list - * + * * @return */ public String[] getAttributes() { - return attributeList.toArray(new String[groupList.size()]); + return attributeList.toArray(new String[attributeList.size()]); } /** * Get the group name from the display name. - * + * * @param displayName * @return */ diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/DataView.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/DataView.java new file mode 100644 index 0000000000..73ba4e3300 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/DataView.java @@ -0,0 +1,77 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.stats.util; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.raytheon.uf.common.units.DataSizeUnit; + +/** + * Data view enumeration. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2013    1357    mpduff      Moved to its own file.
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public enum DataView { + AVG("Average"), MIN("Minimum"), MAX("Maximum"), SUM("Sum"), COUNT("Count"); + + private final String view; + + private DataView(String view) { + this.view = view; + } + + public String getView() { + return view; + } + + private static final Map LOOKUP_MAP; + static { + Map map = new HashMap(); + for (DataView view : DataView.values()) { + map.put(view.getView(), view); + } + LOOKUP_MAP = Collections.unmodifiableMap(map); + } + + /** + * Retrieve the {@link DataSizeUnit} for its string representation. + * + * @param asString + * @return + */ + public static DataView fromString(String asString) { + return LOOKUP_MAP.get(asString); + } + +} \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/UnitUtils.java b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/UnitUtils.java index 3369c245a6..0dbb319678 100644 --- a/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/UnitUtils.java +++ b/edexOsgi/com.raytheon.uf.common.stats/src/com/raytheon/uf/common/stats/util/UnitUtils.java @@ -19,125 +19,113 @@ **/ package com.raytheon.uf.common.stats.util; +import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; +import com.google.common.annotations.VisibleForTesting; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; -import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.units.DataSizeUnit; /** * Utility class for data size conversions. KB vs MB vs GB - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Nov 14, 2012    728     mpduff      Initial creation.
- *
+ * Jan 17, 2013   1357     mpduff      Refactored to use DataSizeUnit and TimeUnit.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ @DynamicSerialize public class UnitUtils implements ISerializableObject { - /** Bytes per Kilobyte */ - private static final double BYTES_PER_KILOBYTE = 1024.0; - /** Different unit types for statistics */ public static enum UnitTypes { DATA_SIZE, TIME, COUNT } /** - * Data Size Conversions + * Time Conversions. */ - public static enum DataSize { - KB("KB", BYTES_PER_KILOBYTE), MB("MB", BYTES_PER_KILOBYTE - * BYTES_PER_KILOBYTE), GB("GB", BYTES_PER_KILOBYTE - * BYTES_PER_KILOBYTE * BYTES_PER_KILOBYTE); + public static enum TimeConversion { + MS("ms", "MILLISECONDS"), Second("Seconds", "SECONDS"), Minute( + "Minutes", "MINUTES"), Hour("Hours", "HOURS"); private final String unit; - private final double conversion; + private final String fullUnit; - private static Set dataUnits; + private TimeUnit timeUnit; - private DataSize(String unit, double conversion) { + private TimeConversion(String unit, String fullUnit) { this.unit = unit; - this.conversion = conversion; - populateSet(); - } - - private static void populateSet() { - dataUnits = new HashSet(); - dataUnits.add("KB"); - dataUnits.add("MB"); - dataUnits.add("GB"); + this.fullUnit = fullUnit; + timeUnit = TimeUnit.valueOf(fullUnit); } public String getDataUnit() { return unit; } - public double getConversion() { - return conversion; + public String getFullUnit() { + return fullUnit; } - public static Set getDataUnits() { - return dataUnits; + public TimeUnit getTimeUnit() { + return timeUnit; + } + + public static TimeConversion getInstance(String unit) { + return TIME_UNIT_LOOKUP.get(unit); } } /** - * Time Conversions. + * Data size unit lookup map. */ - public static enum TimeConversion { - MS("ms", 1), Second("seconds", TimeUtil.MILLIS_PER_SECOND), Minute( - "minutes", TimeUtil.MILLIS_PER_MINUTE), Hour("hours", - TimeUtil.MILLIS_PER_HOUR); - - private static Set dataUnits; - - private final String unit; - - private final double conversion; - - private TimeConversion(String unit, double conversion) { - this.unit = unit; - this.conversion = conversion; - populateSet(); + private static final Map DATA_SIZE_UNIT_LOOKUP; + static { + DataSizeUnit[] values = DataSizeUnit.values(); + Map map = new LinkedHashMap( + values.length); + for (DataSizeUnit dataSize : values) { + map.put(dataSize.getUnit(), dataSize); } + DATA_SIZE_UNIT_LOOKUP = Collections.unmodifiableMap(map); + } - private static void populateSet() { - dataUnits = new HashSet(); - dataUnits.add("seconds"); - dataUnits.add("ms"); - dataUnits.add("minutes"); - dataUnits.add("hours"); - } - - public String getDataUnit() { - return unit; - } - - public double getConversion() { - return conversion; - } - - public static Set getDataUnits() { - return dataUnits; + /** + * Time unit lookup map. + */ + private static final Map TIME_UNIT_LOOKUP; + static { + TimeConversion[] values = TimeConversion.values(); + Map map = new LinkedHashMap( + values.length); + for (TimeConversion timeConversion : values) { + map.put(timeConversion.getDataUnit(), timeConversion); } + TIME_UNIT_LOOKUP = Collections.unmodifiableMap(map); } /** The event type */ + @DynamicSerializeElement private String eventType; /** The data type */ + @DynamicSerializeElement private String dataType; /** The display unit */ @@ -148,10 +136,6 @@ public class UnitUtils implements ISerializableObject { @DynamicSerializeElement private UnitTypes unitType; - /** Copnversion factor */ - @DynamicSerializeElement - private double conversion = 1; - /** * Constructor */ @@ -161,7 +145,7 @@ public class UnitUtils implements ISerializableObject { /** * Constructor - * + * * @param eventType * event type * @param dataType @@ -174,38 +158,6 @@ public class UnitUtils implements ISerializableObject { this.unitType = UnitTypes.COUNT; } - /** - * The largest value of the data set. This is used to determine which - * conversion to use if one is not specified. - * - * @param value - * Largest value of the data set - * - * @return The conversion factor - */ - public void setConversion(double value) { - // Which unit type is it? - if (unitType == UnitTypes.COUNT) { - conversion = 1; - } else if (unitType == UnitTypes.DATA_SIZE) { - if (value < DataSize.MB.getConversion()) { - conversion = DataSize.KB.getConversion(); - } else if (value < DataSize.GB.getConversion()) { - conversion = DataSize.MB.getConversion(); - } else if (value >= DataSize.GB.getConversion()) { - conversion = DataSize.GB.getConversion(); - } - } else if (unitType == UnitTypes.TIME) { - if (value < TimeUtil.MILLIS_PER_MINUTE) { - conversion = TimeUtil.MILLIS_PER_SECOND; - } else if (value < TimeUtil.MILLIS_PER_HOUR) { - conversion = TimeUtil.MILLIS_PER_MINUTE; - } else { - conversion = TimeUtil.MILLIS_PER_SECOND; - } - } - } - /** * @return the eventType */ @@ -220,15 +172,6 @@ public class UnitUtils implements ISerializableObject { return dataType; } - /** - * Get the conversion - * - * @return - */ - public double getConversion() { - return conversion; - } - /** * @return the unitType */ @@ -252,36 +195,139 @@ public class UnitUtils implements ISerializableObject { } /** - * Set the display unit. - * * @param displayUnit + * the displayUnit to set */ public void setDisplayUnit(String displayUnit) { this.displayUnit = displayUnit; + setUnitType(displayUnit); + } - // Determine the unitType - if (DataSize.getDataUnits().contains(displayUnit)) { - unitType = UnitTypes.DATA_SIZE; - } else if (TimeConversion.getDataUnits().contains(displayUnit)) { - unitType = UnitTypes.TIME; - } + /** + * @param eventType + * the eventType to set + */ + public void setEventType(String eventType) { + this.eventType = eventType; + } - if (unitType == UnitTypes.DATA_SIZE) { - if (displayUnit.equals(DataSize.KB.getDataUnit())) { - conversion = DataSize.KB.getConversion(); - } else if (displayUnit.equals(DataSize.MB.getDataUnit())) { - conversion = DataSize.MB.getConversion(); - } else if (displayUnit.equals(DataSize.GB.getDataUnit())) { - conversion = DataSize.GB.getConversion(); - } - } else if (unitType == UnitTypes.TIME) { - if (displayUnit.equals(TimeConversion.MS.getDataUnit())) { - conversion = 1; - } else if (displayUnit.equals(TimeConversion.Second.getDataUnit())) { - conversion = TimeUtil.MILLIS_PER_SECOND; - } else if (displayUnit.equals(TimeConversion.Minute.getDataUnit())) { - conversion = TimeUtil.MILLIS_PER_MINUTE; - } + /** + * @param dataType + * the dataType to set + */ + public void setDataType(String dataType) { + this.dataType = dataType; + } + + /** + * Set the unit type based on the display unit. + * + * @param displayUnit + * The display unit + */ + public void setUnitType(String displayUnit) { + if (TIME_UNIT_LOOKUP.containsKey(displayUnit)) { + this.setUnitType(UnitTypes.TIME); + } else if (DATA_SIZE_UNIT_LOOKUP.containsKey(displayUnit)) { + this.setUnitType(UnitTypes.DATA_SIZE); } } + + /** + * Get the available units for the provided unit type. + * + * @param type + * The type of unit + * @return The available units + */ + @VisibleForTesting + public Set getUnitOptions(UnitTypes type) { + Set units = Collections.emptySet(); + + switch (type) { + case DATA_SIZE: + units = DATA_SIZE_UNIT_LOOKUP.keySet(); + break; + case TIME: + units = TIME_UNIT_LOOKUP.keySet(); + break; + case COUNT: + units = new HashSet(); + units.add("Count"); + break; + default: + break; + } + + return units; + } + + /** + * Convert the value in original units to displayUnits. + * + * @param unit + * original unit + * @param value + * in bytes + * @return converted value + */ + @VisibleForTesting + public double convertDataSizeValue(DataSizeUnit unit, double value) { + DataSizeUnit ds = DataSizeUnit.fromString(displayUnit); + if (ds != null) { + if (ds == DataSizeUnit.BYTE) { + return unit.toByte((long) value); + } else if (ds == DataSizeUnit.KB) { + return unit.toKB((long) value); + } else if (ds == DataSizeUnit.MB) { + return unit.toMB((long) value); + } else if (ds == DataSizeUnit.GB) { + return unit.toGB((long) value); + } + + return value; + } + + return value; + } + + /** + * Convert a time from one unit to the display unit. + * + * @param unit + * Originating unit + * @param value + * value to convert + * @return value converted to display unit + */ + @VisibleForTesting + public long convertTimeValue(TimeConversion unit, long value) { + TimeConversion outputTc = TimeConversion.getInstance(displayUnit); + return outputTc.getTimeUnit().convert(value, unit.getTimeUnit()); + } + + /** + * Convert the provided value. Time types expect source units to be ms and + * data size units to be Bytes. + * + * @param value + * @param view + * @param displayUnit + * @return The converted value + */ + public double convertValue(double value) { + if (getUnitType() == UnitTypes.TIME) { + return convertTimeValue(TimeConversion.MS, (long) value); + } else { + return convertDataSizeValue(DataSizeUnit.BYTE, value); + } + + } + + /** + * Get the different unit options for the provided unit type. + */ + public Set getUnitOptions() { + return this.getUnitOptions(this.unitType); + } } diff --git a/edexOsgi/com.raytheon.uf.common.time/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.time/META-INF/MANIFEST.MF index e2914c2ca3..5cc9c2faac 100644 --- a/edexOsgi/com.raytheon.uf.common.time/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.time/META-INF/MANIFEST.MF @@ -18,5 +18,7 @@ Import-Package: javax.persistence, Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization Export-Package: com.raytheon.uf.common.time, com.raytheon.uf.common.time.adapter, + com.raytheon.uf.common.time.domain, + com.raytheon.uf.common.time.domain.api, com.raytheon.uf.common.time.msgs, com.raytheon.uf.common.time.util diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/Duration.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/Duration.java new file mode 100644 index 0000000000..0ccd973755 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/Duration.java @@ -0,0 +1,165 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import java.util.concurrent.TimeUnit; + +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdapter; +import com.raytheon.uf.common.time.domain.api.IDuration; + +/** + * Implementation of {@link IDuration}. Intentionally package-private as it is + * an implementation detail, and not part of the public API. All access should + * be constrained through {@link Durations}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 10, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlJavaTypeAdapter(value = IDurationTypeAdapter.class) +@DynamicSerializeTypeAdapter(factory = IDurationTypeAdapter.class) +class Duration implements IDuration { + + private final long valueAsNanoseconds; + + /** + * Constructor. + * + * @param value + * the unit value + * @param unit + * the unit + */ + Duration(long value, TimeUnit unit) { + this.valueAsNanoseconds = unit.toNanos(value); + } + + /** + * {@inheritDoc} + */ + @Override + public long getNanos() { + return convert(TimeUnit.NANOSECONDS); + } + + /** + * {@inheritDoc} + */ + @Override + public long getMicros() { + return convert(TimeUnit.MICROSECONDS); + } + + /** + * {@inheritDoc} + */ + @Override + public long getMillis() { + return convert(TimeUnit.MILLISECONDS); + } + + /** + * {@inheritDoc} + */ + @Override + public long getSeconds() { + return convert(TimeUnit.SECONDS); + } + + /** + * {@inheritDoc} + */ + @Override + public long getMinutes() { + return convert(TimeUnit.MINUTES); + } + + /** + * {@inheritDoc} + */ + @Override + public long getHours() { + return convert(TimeUnit.HOURS); + } + + /** + * {@inheritDoc} + */ + @Override + public long getDays() { + return convert(TimeUnit.DAYS); + } + + private long convert(TimeUnit targetUnit) { + return targetUnit.convert(valueAsNanoseconds, TimeUnit.NANOSECONDS); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof IDuration) { + IDuration other = (IDuration) obj; + return other.getNanos() == this.getNanos(); + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return (int) this.getNanos(); + } + + /** + * {@inheritDoc} + */ + @Override + public Duration plus(IDuration anotherDuration) { + return new Duration(getNanos() + anotherDuration.getNanos(), + TimeUnit.NANOSECONDS); + } + + /** + * {@inheritDoc} + */ + @Override + public Duration minus(IDuration anotherDuration) { + return new Duration(getNanos() - anotherDuration.getNanos(), + TimeUnit.NANOSECONDS); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return Durations.toString(this); + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/Durations.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/Durations.java new file mode 100644 index 0000000000..59b54f1b98 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/Durations.java @@ -0,0 +1,140 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.raytheon.uf.common.time.domain.api.IDuration; +import com.raytheon.uf.common.time.domain.api.ITimePoint; + +/** + * Retrieve {@link IDuration}s. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 11, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public final class Durations { + + private static final Pattern DURATION_PATTERN = Pattern + .compile("\\s*(\\d+)\\s+([^\\s]+)\\s*"); + + public static final IDuration ZERO = Durations + .of(0L, TimeUnit.MILLISECONDS); + + /** + * Retrieve a {@link IDuration} of the specified value and unit. + * + * @param value + * @param unit + * @return the duration + */ + public static IDuration of(long value, TimeUnit unit) { + return new Duration(value, unit); + } + + /** + * Retrieve the duration between two {@link TimePoint}s. + * + * @param start + * the starting time point + * @param end + * the ending time point + * @return the duration between the two points + */ + public static IDuration between(ITimePoint start, ITimePoint end) { + final long millis = end.asMilliseconds() - start.asMilliseconds(); + return of(millis, TimeUnit.MILLISECONDS); + } + + /** + * Parse a string representation of a {@link Duration}. + * + * @param asString + * the string representation of the duration + * + * @return the duration + * @throws IllegalArgumentException + * if the argument cannot be parsed into a duration + */ + public static IDuration fromString(String asString) { + final Matcher m = DURATION_PATTERN.matcher(asString); + if (m.matches()) { + return of(Long.parseLong(m.group(1)), TimeUnit.valueOf(m.group(2))); + } + + throw new IllegalArgumentException("The argument [" + asString + + "] does not match a duration!"); + } + + /** + * Convert the {@link IDuration} to a string representation. This method + * figures out the "optimal" unit to display the time in, e.g. 120 minutes + * would display as "2 HOURS", but 128 minutes will be displayed as "128 + * MINUTES". + * + * @param duration + * the duration instance + * @return the string representation + */ + public static String toString(IDuration duration) { + TimeUnit timeUnitForDisplay = TimeUnit.DAYS; + + final TimeUnit[] values = TimeUnit.values(); + final long nanos = duration.getNanos(); + for (int unitIdx = 1; unitIdx < values.length; unitIdx++) { + final TimeUnit timeUnitToTry = values[unitIdx]; + + // If we would lose precision, then use the time unit before this + // one + final long valueInNewTimeUnit = timeUnitToTry.convert(nanos, + TimeUnit.NANOSECONDS); + final boolean wouldLosePrecision = timeUnitToTry + .toNanos(valueInNewTimeUnit) != nanos; + if (wouldLosePrecision) { + timeUnitForDisplay = values[unitIdx - 1]; + break; + } + } + + // Now construct and return the pretty version of the String + final long convertedValue = timeUnitForDisplay.convert(nanos, + TimeUnit.NANOSECONDS); + return convertedValue + " " + timeUnitForDisplay.toString(); + } + + /** + * Disabled constructor. + */ + private Durations() { + } +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/IDurationTypeAdapter.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/IDurationTypeAdapter.java new file mode 100644 index 0000000000..0e8d88ce93 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/IDurationTypeAdapter.java @@ -0,0 +1,86 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import java.util.concurrent.TimeUnit; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.time.domain.api.IDuration; + +/** + * {@link ISerializationTypeAdapter} for {@link IDuration} instances. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 11, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class IDurationTypeAdapter extends XmlAdapter + implements + ISerializationTypeAdapter { + + /** + * {@inheritDoc} + */ + @Override + public void serialize(ISerializationContext serializer, IDuration object) + throws SerializationException { + serializer.writeI64(object.getNanos()); + } + + /** + * {@inheritDoc} + */ + @Override + public IDuration deserialize(IDeserializationContext deserializer) + throws SerializationException { + return Durations.of(deserializer.readI64(), TimeUnit.NANOSECONDS); + } + + /** + * {@inheritDoc} + */ + @Override + public IDuration unmarshal(String v) throws Exception { + return Durations.fromString(v); + } + + /** + * {@inheritDoc} + */ + @Override + public String marshal(IDuration v) throws Exception { + return Durations.toString(v); + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/ITimeIntervalTypeAdapter.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/ITimeIntervalTypeAdapter.java new file mode 100644 index 0000000000..4bb85f810a --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/ITimeIntervalTypeAdapter.java @@ -0,0 +1,93 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.time.domain.api.ITimeInterval; +import com.raytheon.uf.common.time.domain.api.ITimePoint; + +/** + * {@link ISerializationTypeAdapter} for {@link ITimePoint} instances. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class ITimeIntervalTypeAdapter extends + XmlAdapter implements + ISerializationTypeAdapter { + /** + * {@inheritDoc} + */ + @Override + public void serialize(ISerializationContext serializer, ITimeInterval object) + throws SerializationException { + serializer.writeObject(object.getStart()); + serializer.writeObject(object.getEnd()); + } + + /** + * {@inheritDoc} + */ + @Override + public ITimeInterval deserialize(IDeserializationContext deserializer) + throws SerializationException { + ITimePoint start = (ITimePoint) deserializer.readObject(); + ITimePoint end = (ITimePoint) deserializer.readObject(); + + return TimeIntervals.fromTimePoints(start, end); + } + + /** + * {@inheritDoc} + */ + @Override + public ITimeInterval unmarshal(TimeIntervalJaxbable v) + throws Exception { + return TimeIntervals.fromTimePoints(TimePoints.fromDate(v.getStart()), + TimePoints.fromDate(v.getEnd())); + } + + /** + * {@inheritDoc} + */ + @Override + public TimeIntervalJaxbable marshal(ITimeInterval v) throws Exception { + TimeIntervalJaxbable jaxbable = new TimeIntervalJaxbable(); + jaxbable.setStart(v.getStart().asDate()); + jaxbable.setEnd(v.getEnd().asDate()); + + return jaxbable; + } +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/ITimePointTypeAdapter.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/ITimePointTypeAdapter.java new file mode 100644 index 0000000000..e9e44f50bf --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/ITimePointTypeAdapter.java @@ -0,0 +1,83 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import java.util.Date; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.time.domain.api.ITimePoint; + +/** + * {@link ISerializationTypeAdapter} for {@link ITimePoint} instances. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class ITimePointTypeAdapter extends XmlAdapter + implements ISerializationTypeAdapter { + /** + * {@inheritDoc} + */ + @Override + public void serialize(ISerializationContext serializer, ITimePoint object) + throws SerializationException { + serializer.writeI64(object.asMilliseconds()); + } + + /** + * {@inheritDoc} + */ + @Override + public ITimePoint deserialize(IDeserializationContext deserializer) + throws SerializationException { + return TimePoints.fromMillis(deserializer.readI64()); + } + + /** + * {@inheritDoc} + */ + @Override + public ITimePoint unmarshal(Date v) throws Exception { + return TimePoints.fromDate(v); + } + + /** + * {@inheritDoc} + */ + @Override + public Date marshal(ITimePoint v) throws Exception { + return v.asDate(); + } +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeInterval.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeInterval.java new file mode 100644 index 0000000000..cd488c4fc8 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeInterval.java @@ -0,0 +1,136 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdapter; +import com.raytheon.uf.common.time.domain.api.IDuration; +import com.raytheon.uf.common.time.domain.api.ITimeInterval; +import com.raytheon.uf.common.time.domain.api.ITimePoint; + +/** + * Implementation of {@link ITimeInterval}. Intentionally package-private as it + * is an implementation detail, and not part of the public API. All access + * should be constrained through {@link TimeIntervals}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlJavaTypeAdapter(value = ITimeIntervalTypeAdapter.class) +@DynamicSerializeTypeAdapter(factory = ITimeIntervalTypeAdapter.class) +class TimeInterval implements ITimeInterval { + + private final ITimePoint intervalStart; + + private final ITimePoint intervalEnd; + + /** + * Constructor. + * + * @param intervalStart + * the start of the interval + * @param intervalEnd + * the end of the interval + */ + TimeInterval(ITimePoint intervalStart, ITimePoint intervalEnd) { + this.intervalStart = intervalStart; + this.intervalEnd = intervalEnd; + } + + /** + * {@inheritDoc} + */ + @Override + public ITimePoint getStart() { + return intervalStart; + } + + /** + * {@inheritDoc} + */ + @Override + public ITimePoint getEnd() { + return intervalEnd; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean containsTimePoint(ITimePoint timePoint) { + final boolean intervalStartSameOrBefore = intervalStart + .isBefore(timePoint) || intervalStart.isSame(timePoint); + final boolean intervalEndSameOrAfter = intervalEnd.isAfter(timePoint) + || intervalEnd.isSame(timePoint); + + return intervalStartSameOrBefore && intervalEndSameOrAfter; + } + + /** + * {@inheritDoc} + */ + @Override + public IDuration getDuration() { + return Durations.between(intervalStart, intervalEnd); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof ITimeInterval) { + ITimeInterval other = (ITimeInterval) obj; + + return this.getStart().equals(other.getStart()) + && this.getEnd().equals(other.getEnd()); + } + return super.equals(obj); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return getStart().hashCode() + getEnd().hashCode(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("start [").append(getStart()).append("]"); + sb.append(" end [").append(getEnd()).append("]"); + sb.append(" duration [").append(getDuration()).append("]"); + + return sb.toString(); + } +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeIntervalJaxbable.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeIntervalJaxbable.java new file mode 100644 index 0000000000..67e1050e7a --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeIntervalJaxbable.java @@ -0,0 +1,91 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import com.raytheon.uf.common.time.domain.api.ITimeInterval; + +/** + * Representation of a {@link ITimeInterval} for the purpose of JAXB. This class + * should only be used for converting to and from JAXB in + * {@link ITimeIntervalTypeAdapter}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(propOrder = { "start", "end" }) +public class TimeIntervalJaxbable { + + @XmlElement(required = true) + private Date start; + + @XmlElement(required = true) + private Date end; + + /** + * @return the start + */ + public Date getStart() { + return start; + } + + /** + * @param start + * the start to set + */ + public void setStart(Date start) { + this.start = start; + } + + /** + * @return the end + */ + public Date getEnd() { + return end; + } + + /** + * @param end + * the end to set + */ + public void setEnd(Date end) { + this.end = end; + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeIntervals.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeIntervals.java new file mode 100644 index 0000000000..e6a67bcc1d --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimeIntervals.java @@ -0,0 +1,69 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import com.raytheon.uf.common.time.domain.api.ITimeInterval; +import com.raytheon.uf.common.time.domain.api.ITimePoint; + +/** + * Utility class to work with {@link ITimeInterval}s + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public final class TimeIntervals { + + /** + * Construct a {@link ITimeInterval} from two {@link ITimePoint}s. + * + * @param start + * the start of the time interval + * @param end + * the end of the time interval + * @return the interval + */ + public static ITimeInterval fromTimePoints(ITimePoint start, ITimePoint end) { + if (end.isBefore(start)) { + throw new IllegalArgumentException( + "The end time point cannot be before the start time point:\n[end = " + + end + "] [start = " + start + "]"); + } + return new TimeInterval(start, end); + } + + /** + * No construction. + */ + private TimeIntervals() { + + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimePoint.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimePoint.java new file mode 100644 index 0000000000..30be544084 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimePoint.java @@ -0,0 +1,148 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import java.util.Date; + +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdapter; +import com.raytheon.uf.common.time.domain.api.ITimeInterval; +import com.raytheon.uf.common.time.domain.api.ITimePoint; +import com.raytheon.uf.common.time.util.TimeUtil; + +/** + * Implementation of {@link ITimePoint}. Intentionally package-private as it is + * an implementation detail, and not part of the public API. All access should + * be constrained through {@link TimePoints}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlJavaTypeAdapter(value = ITimePointTypeAdapter.class) +@DynamicSerializeTypeAdapter(factory = ITimePointTypeAdapter.class) +class TimePoint implements ITimePoint { + + private final long milliseconds; + + /** + * Construct a {@link TimePoint} for the specified milliseconds. + * + * @param milliseconds + */ + TimePoint(long milliseconds) { + this.milliseconds = milliseconds; + } + + /** + * Deep-copy another {@link ITimePoint}. + * + * @param toCopy + */ + TimePoint(ITimePoint toCopy) { + this(toCopy.asMilliseconds()); + } + + /** + * {@inheritDoc} + */ + @Override + public Date asDate() { + return new Date(milliseconds); + } + + /** + * {@inheritDoc} + */ + @Override + public long asMilliseconds() { + return milliseconds; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAfter(ITimePoint anotherTimePoint) { + return this.asMilliseconds() > anotherTimePoint.asMilliseconds(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isBefore(ITimePoint anotherTimePoint) { + return this.asMilliseconds() < anotherTimePoint.asMilliseconds(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isSame(ITimePoint anotherPoint) { + return this.asMilliseconds() == anotherPoint.asMilliseconds(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isWithin(ITimeInterval interval) { + return interval.containsTimePoint(this); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof ITimePoint) { + ITimePoint other = (ITimePoint) obj; + return this.isSame(other); + } + return super.equals(obj); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return (int) asMilliseconds(); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return TimeUtil.formatDate(asDate()); + } +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimePoints.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimePoints.java new file mode 100644 index 0000000000..3360c7e2b9 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/TimePoints.java @@ -0,0 +1,75 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import java.util.Date; + +import com.raytheon.uf.common.time.domain.api.ITimePoint; +import com.raytheon.uf.common.time.util.TimeUtil; + +/** + * Utility class to work with {@link ITimePoint}s. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public final class TimePoints { + + /** + * Return the {@link ITimePoint} instance for the specified milliseconds. + * + * @return the milliseconds as an {@link ITimePoint} + */ + public static ITimePoint fromMillis(long milliseconds) { + return new TimePoint(milliseconds); + } + + /** + * Return the {@link ITimePoint} instance for the specified {@link Date}. + * + * @return the date as an {@link ITimePoint} + */ + public static ITimePoint fromDate(Date date) { + return new TimePoint(date.getTime()); + } + + /** + * Return the {@link ITimePoint} instance of the current time. + * + * @return now, as an {@link ITimePoint} + */ + public static ITimePoint now() { + return fromDate(TimeUtil.newImmutableDate()); + } + + private TimePoints() { + } +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/IDuration.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/IDuration.java new file mode 100644 index 0000000000..250f649f57 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/IDuration.java @@ -0,0 +1,138 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain.api; + +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import javax.xml.datatype.Duration; + +import com.raytheon.uf.common.time.domain.IDurationTypeAdapter; + +/** + * Interface for a duration. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 11, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlJavaTypeAdapter(value = IDurationTypeAdapter.class) +public interface IDuration { + + /** + * Retrieve the number of nanoseconds represented by the duration. + * Conversions from finer to coarser granularities truncate, so lose + * precision. For example converting 999 milliseconds to seconds + * results in 0. + * + * @return the number of nanoseconds, or 0 if the converted value is less + * than 1 of the new unit + */ + long getNanos(); + + /** + * Retrieve the number of microseconds represented by the duration. + * Conversions from finer to coarser granularities truncate, so lose + * precision. For example converting 999 milliseconds to seconds + * results in 0. + * + * @return the number of microseconds, or 0 if the converted value is less + * than 1 of the new unit + */ + long getMicros(); + + /** + * Retrieve the number of milliseconds represented by the duration. + * Conversions from finer to coarser granularities truncate, so lose + * precision. For example converting 999 milliseconds to seconds + * results in 0. + * + * @return the number of milliseconds, or 0 if the converted value is less + * than 1 of the new unit + */ + long getMillis(); + + /** + * Retrieve the number of seconds represented by the duration. Conversions + * from finer to coarser granularities truncate, so lose precision. For + * example converting 999 milliseconds to seconds results in + * 0. + * + * @return the number of seconds, or 0 if the converted value is less than 1 + * of the new unit + */ + long getSeconds(); + + /** + * Retrieve the number of minutes represented by the duration. Conversions + * from finer to coarser granularities truncate, so lose precision. For + * example converting 999 milliseconds to seconds results in + * 0. + * + * @return the number of minutes, or 0 if the converted value is less than 1 + * of the new unit + */ + long getMinutes(); + + /** + * Retrieve the number of hours represented by the duration. Conversions + * from finer to coarser granularities truncate, so lose precision. For + * example converting 999 milliseconds to seconds results in + * 0. + * + * @return the number of hours, or 0 if the converted value is less than 1 + * of the new unit + */ + long getHours(); + + /** + * Retrieve the number of hours represented by the duration. Conversions + * from finer to coarser granularities truncate, so lose precision. For + * example converting 999 milliseconds to seconds results in + * 0. + * + * @return the number of days, or 0 if the converted value is less than 1 of + * the new unit + */ + long getDays(); + + /** + * Add another {@link Duration} to this one. + * + * @param anotherDuration + * @return the duration of the sum + */ + IDuration plus(IDuration anotherDuration); + + /** + * Subtract another {@link Duration} from this one. + * + * @param anotherDuration + * @return the duration of the difference + */ + IDuration minus(IDuration anotherDuration); +} \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/ITimeInterval.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/ITimeInterval.java new file mode 100644 index 0000000000..49c5be0afb --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/ITimeInterval.java @@ -0,0 +1,75 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain.api; + +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.raytheon.uf.common.time.domain.ITimeIntervalTypeAdapter; + +/** + * Represents a specific interval in time. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlJavaTypeAdapter(value = ITimeIntervalTypeAdapter.class) +public interface ITimeInterval { + + /** + * Return the start {@link ITimePoint} of the {@link ITimeInterval}. + * + * @return the time point the interval started + */ + ITimePoint getStart(); + + /** + * Return the end {@link ITimePoint} of the {@link ITimeInterval}. + * + * @return the time point the interval ended + */ + ITimePoint getEnd(); + + /** + * Check whether an {@link ITimePoint} falls within the + * {@link ITimeInterval}. + * + * @param timePoint + * the time point + * @return true if the interval contains the point + */ + boolean containsTimePoint(ITimePoint timePoint); + + /** + * Retrieve the duration of the {@link ITimeInterval}. + * + * @return the duration + */ + IDuration getDuration(); +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/ITimePoint.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/ITimePoint.java new file mode 100644 index 0000000000..e6edd4c530 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/domain/api/ITimePoint.java @@ -0,0 +1,98 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain.api; + +import java.util.Date; + +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.raytheon.uf.common.time.domain.ITimePointTypeAdapter; + +/** + * Represents an instance in time. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@XmlJavaTypeAdapter(value = ITimePointTypeAdapter.class) +public interface ITimePoint { + + /** + * Return the {@link ITimePoint} as a {@link Date}. + * + * @return the {@link ITimePoint} as a {@link Date} + */ + Date asDate(); + + /** + * Return the {@link ITimePoint} as the milliseconds which would be returned + * by {@link Date}. + * + * @return the milliseconds + */ + long asMilliseconds(); + + /** + * Check whether this {@link ITimePoint} is before another one. + * + * @param anotherPoint + * the other {@link ITimePoint} + * @return true if this point in time is before the other one + */ + boolean isBefore(ITimePoint anotherPoint); + + /** + * Check whether this {@link ITimePoint} is after another one. + * + * @param anotherPoint + * the other {@link ITimePoint} + * @return true if this point in time is after the other one + */ + boolean isAfter(ITimePoint anotherPoint); + + /** + * Check whether this {@link ITimePoint} is the same as another one. + * + * @param anotherPoint + * the other {@link ITimePoint} + * @return true if this point in time is the same as the other one + */ + boolean isSame(ITimePoint anotherPoint); + + /** + * Check whether this {@link ITimePoint} falls within the specified + * {@link ITimeInterval}. + * + * @param interval + * the {@link ITimeInterval} + * @return true if this point in time is within the time interval + */ + boolean isWithin(ITimeInterval interval); +} diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/AbstractTimer.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/AbstractTimer.java index 0be0ed7b40..213d0d5681 100644 --- a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/AbstractTimer.java +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/AbstractTimer.java @@ -1,5 +1,8 @@ package com.raytheon.uf.common.time.util; +import com.raytheon.uf.common.time.domain.Durations; +import com.raytheon.uf.common.time.domain.api.IDuration; +import com.raytheon.uf.common.time.domain.api.ITimePoint; /** * @@ -13,19 +16,19 @@ package com.raytheon.uf.common.time.util; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Aug 16, 2012 0743 djohnson Initial creation + * Jan 14, 2013 1286 djohnson Use time domain API. * * * * @author djohnson * @version 1.0 */ -// @NotThreadSafe abstract class AbstractTimer implements ITimer { - private long start; + private ITimePoint start; - private long stop; + private ITimePoint stop; - private long elapsedTime; + private IDuration elapsedTime = Durations.ZERO; /** * {@inheritDoc} @@ -33,8 +36,8 @@ abstract class AbstractTimer implements ITimer { @Override public void start() { if (isTimerStopped()) { - elapsedTime += (stop - start); - stop = 0; + elapsedTime = elapsedTime.plus(Durations.between(start, stop)); + stop = null; } else if (isTimerStarted()) { throw new IllegalStateException( "A timer that is running must be stopped before start() is called again!"); @@ -62,8 +65,21 @@ abstract class AbstractTimer implements ITimer { */ @Override public long getElapsedTime() { - long currentOrStopTime = (isTimerRunning()) ? getCurrentTime() : stop; - return (currentOrStopTime - start) + elapsedTime; + return getElapsed().getMillis(); + } + + /** + * {@inheritDoc} + */ + @Override + public IDuration getElapsed() { + ITimePoint currentOrStopTime = (isTimerRunning()) ? getCurrentTime() + : stop; + if (currentOrStopTime == null && start == null) { + return Durations.ZERO; + } + IDuration currentRun = Durations.between(start, currentOrStopTime); + return currentRun.plus(elapsedTime); } /** @@ -71,12 +87,12 @@ abstract class AbstractTimer implements ITimer { */ @Override public void reset() { - start = 0; - stop = 0; - elapsedTime = 0; + start = null; + stop = null; + elapsedTime = Durations.ZERO; } - protected abstract long getCurrentTime(); + protected abstract ITimePoint getCurrentTime(); /** * Check whether the timer is actively running. @@ -93,7 +109,7 @@ abstract class AbstractTimer implements ITimer { * @return true if the timer was started */ private boolean isTimerStarted() { - return start > 0; + return start != null; } /** @@ -102,6 +118,6 @@ abstract class AbstractTimer implements ITimer { * @return true if the timer is stopped */ private boolean isTimerStopped() { - return stop > 0; + return stop != null; } } diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/ITimer.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/ITimer.java index 0a028176ad..9fcaccfc58 100644 --- a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/ITimer.java +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/ITimer.java @@ -1,5 +1,7 @@ package com.raytheon.uf.common.time.util; +import com.raytheon.uf.common.time.domain.api.IDuration; + /** * * Defines a timer that can be started and stopped. @@ -11,6 +13,7 @@ package com.raytheon.uf.common.time.util; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Aug 16, 2012 0743 djohnson Initial creation + * Jan 11, 2013 djohnson Use {@link IDuration}. * * * @@ -43,6 +46,13 @@ public interface ITimer { */ long getElapsedTime(); + /** + * Get the elapsed time + * + * @return the elapsed time + */ + IDuration getElapsed(); + /** * Reset the timer. */ diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java index f236e4d402..ac04d0011f 100644 --- a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java @@ -28,6 +28,8 @@ import java.util.TimeZone; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.SimulatedTime; +import com.raytheon.uf.common.time.domain.TimePoints; +import com.raytheon.uf.common.time.domain.api.ITimePoint; /** * Utilities for time, some extracted from Util. @@ -42,14 +44,16 @@ import com.raytheon.uf.common.time.SimulatedTime; * Nov 09, 2012 1322 djohnson Add SECONDS_PER_MINUTE. * Nov 21, 2012 728 mpduff Added MILLIS_PER_MONTH. * Jan 07, 2013 1451 djohnson Add newGmtCalendar() and time constants. + * Jan 17, 2013 1357 mpduff Change MILLIS_PER_MONTH to MILLIS_PER_30_DAYS + * Jan 22, 2013 1484 mpduff Add HOURS_PER_WEEK. + * Jan 22, 2013 1519 djohnson Add MINUTES_PER_DAY. * * * * @author njensen * @version 1.0 */ - -public class TimeUtil { +public final class TimeUtil { /** * A clock that does not really return the current time. Useful when you @@ -63,9 +67,12 @@ public class TimeUtil { * */ private static class NullClock extends AbstractTimer { + private static final ITimePoint CONSTANT_TIME = TimePoints + .fromMillis(1L); + @Override - protected long getCurrentTime() { - return 1; + protected ITimePoint getCurrentTime() { + return CONSTANT_TIME; } } @@ -91,8 +98,16 @@ public class TimeUtil { public static final int HOURS_PER_DAY = 24; + public static final int HOURS_PER_HALF_DAY = HOURS_PER_DAY / 2; + + public static final int HOURS_PER_QUARTER_DAY = HOURS_PER_HALF_DAY / 2; + + public static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY; + private static final int DAYS_PER_WEEK = 7; + public static final int HOURS_PER_WEEK = HOURS_PER_DAY * DAYS_PER_WEEK; + // Util.java has a few of these constants, but that is located in an EDEX // plugin and this is a more appropriate place for them anyways public static final long MILLIS_PER_SECOND = 1000; @@ -107,10 +122,7 @@ public class TimeUtil { public static final long MILLIS_PER_WEEK = MILLIS_PER_DAY * DAYS_PER_WEEK; - /** - * Note: This constant assumes a month of 30 days. - */ - public static final long MILLIS_PER_MONTH = MILLIS_PER_DAY * 30; + public static final long MILLIS_PER_30_DAYS = MILLIS_PER_DAY * 30; /** * Note: This constant does not take into account leap years. @@ -377,4 +389,10 @@ public class TimeUtil { } return calendar; } + + /** + * Disabled constructor. + */ + private TimeUtil() { + } } diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimerImpl.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimerImpl.java index 337deafa35..3685f77ba1 100644 --- a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimerImpl.java +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimerImpl.java @@ -1,5 +1,8 @@ package com.raytheon.uf.common.time.util; +import com.raytheon.uf.common.time.domain.TimePoints; +import com.raytheon.uf.common.time.domain.api.ITimePoint; + /** * @@ -27,7 +30,7 @@ class TimerImpl extends AbstractTimer { * {@inheritDoc} */ @Override - protected long getCurrentTime() { - return TimeUtil.currentTimeMillis(); + protected ITimePoint getCurrentTime() { + return TimePoints.fromMillis(TimeUtil.currentTimeMillis()); } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSizeUnit.java b/edexOsgi/com.raytheon.uf.common.units/src/com/raytheon/uf/common/units/DataSizeUnit.java similarity index 80% rename from cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSizeUnit.java rename to edexOsgi/com.raytheon.uf.common.units/src/com/raytheon/uf/common/units/DataSizeUnit.java index fb4e427311..89f23ca2d0 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSizeUnit.java +++ b/edexOsgi/com.raytheon.uf.common.units/src/com/raytheon/uf/common/units/DataSizeUnit.java @@ -1,8 +1,11 @@ -package com.raytheon.uf.viz.datadelivery.utils; +package com.raytheon.uf.common.units; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; /** * Enumeration for Data Size units and conversions. Based off of TimeUnit class. @@ -13,14 +16,16 @@ import javax.xml.bind.annotation.XmlType; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 08, 2013 1420 mpduff Initial creation. + * Jan 08, 2013 1420 mpduff Initial creation. + * Jan 14, 2013 1286 djohnson Add lookup map via string version. + * Jan 17, 2013 1357 mpduff Moved to com.raytheon.uf.common.units so other plugins can use it. * * * * @author mpduff * @version 1.0 */ -@XmlType(name = "ruleUnit") + @XmlEnum public enum DataSizeUnit { @XmlEnumValue("Byte") @@ -201,4 +206,23 @@ public enum DataSizeUnit { * @return converted value */ public abstract long convert(long l, DataSizeUnit ds); + + private static final Map LOOKUP_MAP; + static { + Map map = new HashMap(); + for (DataSizeUnit unit : DataSizeUnit.values()) { + map.put(unit.getUnit(), unit); + } + LOOKUP_MAP = Collections.unmodifiableMap(map); + } + + /** + * Retrieve the {@link DataSizeUnit} for its string representation. + * + * @param asString + * @return + */ + public static DataSizeUnit fromString(String asString) { + return LOOKUP_MAP.get(asString); + } } \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthGraphDataAdapter.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthGraphDataAdapter.java index f8b2ac0908..9d012ec956 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthGraphDataAdapter.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthGraphDataAdapter.java @@ -31,6 +31,11 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.raytheon.uf.common.datadelivery.bandwidth.data.BandwidthGraphData; import com.raytheon.uf.common.datadelivery.bandwidth.data.TimeWindowData; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthAllocation; import com.raytheon.uf.edex.datadelivery.bandwidth.dao.SubscriptionDao; @@ -50,7 +55,8 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalPlan.Bandw * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Dec 6, 2012 1397 djohnson Initial creation + * Dec 06, 2012 1397 djohnson Initial creation + * Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * * * @@ -59,6 +65,8 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalPlan.Bandw */ class BandwidthGraphDataAdapter { + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(BandwidthGraphDataAdapter.class); private final RetrievalManager retrievalManager; @@ -88,7 +96,7 @@ class BandwidthGraphDataAdapter { .getBucketMinutes()); Map> dataMap = new HashMap>(); - Map priorityMap = new HashMap(); + Map priorityMap = new HashMap(); Map retrievals = new HashMap(); Multimap reservations = ArrayListMultimap @@ -133,7 +141,16 @@ class BandwidthGraphDataAdapter { final SubscriptionRetrieval value = entry.getValue(); SubscriptionDao dao = value.getSubscriptionDao(); final String subName = dao.getName(); - priorityMap.put(subName, Integer.valueOf((int) dao.getPriority())); + try { + priorityMap.put(subName, dao.getSubscription().getPriority()); + } catch (SerializationException e) { + statusHandler + .handle(Priority.PROBLEM, + "Unable to get access to the actual subscription for [" + + subName + "], skipping...", + e); + continue; + } List timeWindows = dataMap.get(subName); diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java index b037dfb8f9..bcd51a6e14 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java @@ -96,7 +96,9 @@ import com.raytheon.uf.edex.event.EventBus; * Dec 06, 2012 1397 djohnson Add ability to get bandwidth graph data. * Dec 11, 2012 1403 djohnson Adhoc subscriptions no longer go to the registry. * Dec 12, 2012 1286 djohnson Remove shutdown hook and finalize(). - * + * Jan 25, 2013 1528 djohnson Compare priorities as primitive ints. + * Jan 28, 2013 1530 djohnson Unschedule all allocations for a subscription that does not fully schedule. + * Jan 30, 2013 1501 djohnson Fix broken calculations for determining required latency. * * * @author dhladky @@ -567,9 +569,45 @@ abstract class BandwidthManager extends .getCycleTimes()); List unscheduled = schedule(subscription, cycles); + unscheduleSubscriptionsForAllocations(unscheduled); + return unscheduled; } + /** + * Unschedules all subscriptions the allocations are associated to. + * + * @param unscheduled + * the unscheduled allocations + */ + private void unscheduleSubscriptionsForAllocations( + List unscheduled) { + Set subscriptionsToUnschedule = Sets.newHashSet(); + for (BandwidthAllocation unscheduledAllocation : unscheduled) { + if (unscheduledAllocation instanceof SubscriptionRetrieval) { + SubscriptionRetrieval retrieval = (SubscriptionRetrieval) unscheduledAllocation; + try { + subscriptionsToUnschedule.add(retrieval.getSubscription()); + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to deserialize a subscription", e); + continue; + } + } + } + + for (Subscription sub : subscriptionsToUnschedule) { + sub.setUnscheduled(true); + try { + subscriptionUpdated(sub); + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to deserialize a subscription", e); + continue; + } + } + } + /** * {@inheritDoc} * @@ -658,7 +696,8 @@ abstract class BandwidthManager extends // If BandwidthManager does not know about the subscription, and // it's active, attempt to add it.. - if (subscriptionDaos.isEmpty() && subscription.isActive()) { + if (subscriptionDaos.isEmpty() && subscription.isActive() + && !subscription.isUnscheduled()) { final boolean subscribedToCycles = !subscription.getTime() .getCycleTimes().isEmpty(); final boolean useMostRecentDataSetUpdate = !subscribedToCycles; @@ -687,8 +726,8 @@ abstract class BandwidthManager extends unscheduled = schedule(adhoc); } return unscheduled; - } else if (!subscription.isActive()) { - // See if the subscription was inactivated.. + } else if (!subscription.isActive() || subscription.isUnscheduled()) { + // See if the subscription was inactivated or unscheduled.. // Need to remove BandwidthReservations for this // subscription. return remove(subscriptionDaos, true); @@ -796,7 +835,7 @@ abstract class BandwidthManager extends boolean requiresReschedule = (old.getDataSetSize() != subscription .getDataSetSize()) // Priority is different - || (!old.getPriority().equals(subscription.getPriority())) + || (old.getPriority() != subscription.getPriority()) // Latency is different || (!(old.getLatencyInMinutes() == subscription .getLatencyInMinutes())); @@ -1121,8 +1160,7 @@ abstract class BandwidthManager extends * @return the graph data */ private BandwidthGraphData getBandwidthGraphData() { - return new BandwidthGraphDataAdapter(retrievalManager) - .get(); + return new BandwidthGraphDataAdapter(retrievalManager).get(); } /** @@ -1505,95 +1543,86 @@ abstract class BandwidthManager extends * @return the required latency, in minutes */ @VisibleForTesting - int determineRequiredLatency(Subscription subscription) { + int determineRequiredLatency(final Subscription subscription) { ITimer timer = TimeUtil.getTimer(); timer.start(); - try { - final Subscription clone = BandwidthUtil.cheapClone( - Subscription.class, subscription); - if (clone.getLatencyInMinutes() < 1) { - clone.setLatencyInMinutes(1); - } - - boolean foundLatency = false; - int latency = clone.getLatencyInMinutes(); - int previousLatency = latency; - do { - // Double the latency until we have two values we can binary - // search between... - previousLatency = latency; - latency *= 2; - clone.setLatencyInMinutes(latency); - foundLatency = isSchedulableWithoutConflict(clone); - } while (!foundLatency); - - SortedSet possibleLatencies = new TreeSet(); - for (int i = previousLatency; i < (latency + 1); i++) { - possibleLatencies.add(Integer.valueOf(i)); - } - - IBinarySearchResponse response = AlgorithmUtil - .binarySearch(possibleLatencies, new Comparable() { - @Override - public int compareTo(Integer valueToCheck) { - clone.setLatencyInMinutes(valueToCheck); - - boolean latencyWouldWork = isSchedulableWithoutConflict(clone); - - // Check if one value less would not work, if so - // then this is the required latency, otherwise keep - // searching - if (latencyWouldWork) { - clone.setLatencyInMinutes(clone - .getLatencyInMinutes() - 1); - - return (isSchedulableWithoutConflict(clone)) ? 1 - : 0; - } else { - // Still too low, stuff would be unscheduled - return -1; - } - } - }); - - final Integer binarySearchedLatency = response.getItem(); - if (binarySearchedLatency != null) { - latency = binarySearchedLatency.intValue(); - - if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { - statusHandler - .debug(String - .format("Found required latency of [%s] in [%s] iterations", - binarySearchedLatency, - response.getIterations())); - } - } else { - statusHandler - .warn(String - .format("Unable to find the required latency with a binary search, using required latency [%s]", - latency)); - } - - timer.stop(); - - int bufferRoomInMinutes = retrievalManager.getPlan( - subscription.getRoute()).getBucketMinutes(); - - final String logMsg = String - .format("Determined required latency of [%s] in [%s] ms. Adding buffer room of [%s] minutes", - latency, timer.getElapsedTime(), - bufferRoomInMinutes); - statusHandler.info(logMsg); - - latency += bufferRoomInMinutes; - - return latency; - } catch (SerializationException e) { - statusHandler.handle(Priority.PROBLEM, - "Unable to serialize a Subscription", e); - return -1; + boolean foundLatency = false; + int latency = subscription.getLatencyInMinutes(); + if (latency < 1) { + latency = 1; } + int previousLatency = latency; + do { + // Double the latency until we have two values we can binary + // search between... + previousLatency = latency; + latency *= 2; + + Subscription clone = new Subscription(subscription); + clone.setLatencyInMinutes(latency); + foundLatency = isSchedulableWithoutConflict(clone); + } while (!foundLatency); + + SortedSet possibleLatencies = new TreeSet(); + for (int i = previousLatency; i < (latency + 1); i++) { + possibleLatencies.add(Integer.valueOf(i)); + } + + IBinarySearchResponse response = AlgorithmUtil.binarySearch( + possibleLatencies, new Comparable() { + @Override + public int compareTo(Integer valueToCheck) { + Subscription clone = new Subscription(subscription); + clone.setLatencyInMinutes(valueToCheck); + + boolean latencyWouldWork = isSchedulableWithoutConflict(clone); + + // Check if one value less would not work, if so + // then this is the required latency, otherwise keep + // searching + if (latencyWouldWork) { + clone.setLatencyInMinutes(clone + .getLatencyInMinutes() - 1); + + return (isSchedulableWithoutConflict(clone)) ? 1 + : 0; + } else { + // Still too low, stuff would be unscheduled + return -1; + } + } + }); + + final Integer binarySearchedLatency = response.getItem(); + if (binarySearchedLatency != null) { + latency = binarySearchedLatency.intValue(); + + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { + statusHandler.debug(String.format( + "Found required latency of [%s] in [%s] iterations", + binarySearchedLatency, response.getIterations())); + } + } else { + statusHandler + .warn(String + .format("Unable to find the required latency with a binary search, using required latency [%s]", + latency)); + } + + timer.stop(); + + int bufferRoomInMinutes = retrievalManager.getPlan( + subscription.getRoute()).getBucketMinutes(); + + final String logMsg = String + .format("Determined required latency of [%s] in [%s] ms. Adding buffer room of [%s] minutes", + latency, timer.getElapsedTime(), bufferRoomInMinutes); + statusHandler.info(logMsg); + + latency += bufferRoomInMinutes; + + return latency; } /** diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/dao/BandwidthAllocation.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/dao/BandwidthAllocation.java index 683db4760e..5ac5ed34e3 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/dao/BandwidthAllocation.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/dao/BandwidthAllocation.java @@ -298,4 +298,16 @@ public class BandwidthAllocation implements IPersistableDataObject, return sb.toString(); } + /** + * Check whether this allocation is higher priority than another. + * + * @param other + * the other + * @return true if this allocation is higher priority than the other one + */ + public boolean isHigherPriorityThan(BandwidthAllocation other) { + // A lower priority value means it's higher priority + return this.getPriority() < other.getPriority(); + } + } \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/retrieval/PriorityRetrievalScheduler.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/retrieval/PriorityRetrievalScheduler.java index 279c1d87d1..49fa940def 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/retrieval/PriorityRetrievalScheduler.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/retrieval/PriorityRetrievalScheduler.java @@ -28,7 +28,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.util.BandwidthUtil; * Aug 27, 2012 726 jspinks Initial release. * Oct 17, 2012 0726 djohnson If unable to find a bucket with floorKey, use ceilingKey. * Oct 26, 2012 1286 djohnson Return list of unscheduled allocations. - * + * Jan 25, 2013 1528 djohnson Lower priority requests should not be able to unschedule higher priority requests. * * * @version 1.0 @@ -180,7 +180,10 @@ public class PriorityRetrievalScheduler implements IRetrievalScheduler { for (BandwidthBucket bucket : window) { for (BandwidthAllocation o : bucket.getRequests()) { long estimatedSizeInBytes = o.getEstimatedSizeInBytes(); - if (request.getPriority() > o.getPriority()) { + // This was bad... we just about released giving lower + // priority requests the ability to unschedule higher priority + // requests.... + if (request.isHigherPriorityThan(o)) { total += estimatedSizeInBytes; lowerPriorityRequests.add(o); } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java index 62310af045..48587bddec 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java @@ -207,7 +207,7 @@ public class BandwidthUtil { // will have to revisit when other data type are introduced. // perhaps minute of the day? dao.setCycle(baseReferenceTime.get(Calendar.HOUR_OF_DAY)); - dao.setPriority(subscription.getPriority()); + dao.setPriority(subscription.getPriority().getPriorityValue()); dao.setRegistryId(subscription.getId()); return dao; } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/META-INF/MANIFEST.MF index 370aea781a..49bf0e89f1 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/META-INF/MANIFEST.MF @@ -18,4 +18,6 @@ Require-Bundle: com.google.guava;bundle-version="1.0.0", org.springframework;bundle-version="2.5.6", com.raytheon.uf.common.event;bundle-version="1.0.0", com.raytheon.uf.common.datadelivery.registry;bundle-version="1.0.0", - com.raytheon.uf.common.registry.event;bundle-version="1.0.0" + com.raytheon.uf.common.registry.event;bundle-version="1.0.0", + com.raytheon.uf.common.registry.ebxml;bundle-version="1.0.0", + com.raytheon.uf.common.datadelivery.service;bundle-version="1.0.0" diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery-request.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery.xml similarity index 90% rename from edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery-request.xml rename to edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery.xml index 95920aaa57..de3b7a62fd 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery.xml @@ -24,19 +24,19 @@
- + - + - + - + diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/src/com/raytheon/uf/edex/datadelivery/event/handler/SubscriptionNotificationHandler.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/src/com/raytheon/uf/edex/datadelivery/event/handler/SubscriptionNotificationHandler.java index e0a17c731e..cb31c53e84 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/src/com/raytheon/uf/edex/datadelivery/event/handler/SubscriptionNotificationHandler.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/src/com/raytheon/uf/edex/datadelivery/event/handler/SubscriptionNotificationHandler.java @@ -21,21 +21,22 @@ package com.raytheon.uf.edex.datadelivery.event.handler; import java.util.Calendar; -import com.raytheon.uf.common.datadelivery.event.notification.BaseSubscriptionNotificationRequest; -import com.raytheon.uf.common.datadelivery.event.notification.BaseSubscriptionNotificationResponse; import com.raytheon.uf.common.datadelivery.event.notification.NotificationRecord; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.handlers.IBaseSubscriptionHandler; +import com.raytheon.uf.common.datadelivery.service.BaseSubscriptionNotificationRequest; +import com.raytheon.uf.common.datadelivery.service.BaseSubscriptionNotificationResponse; import com.raytheon.uf.common.serialization.comm.IRequestHandler; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; /** * Subscription Notification Handler. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Jun 25, 2012            mpduff     Initial creation.
@@ -44,13 +45,16 @@ import com.raytheon.uf.common.status.UFStatus;
  * Aug 31, 2012    1128    mpduff     Set priority and category from request.
  * Sep 06, 2012     687    mpduff     Send a SubscriptionNotificationResponse object.
  * Sep 24, 2012    1157    mpduff     Changed to use BaseSubscriptionNotificationRequest.
+ * Jan 17, 2013 1501       djohnson     If a subscription is still in the registry, use it for the notification response.
+ * Jan 21, 2013 1501       djohnson     Throw an exception if subscription is not provided on the request.
  * 
- * + * * @author mpduff * @version 1.0 */ -public class SubscriptionNotificationHandler extends AbstractHandler implements +public class SubscriptionNotificationHandler extends + AbstractHandler implements IRequestHandler> { private static final IUFStatusHandler statusHandler = UFStatus @@ -60,7 +64,7 @@ public class SubscriptionNotificationHandler extends Abs /** * Constructor - * + * * @param uri * the jms uri to send the response */ @@ -70,7 +74,7 @@ public class SubscriptionNotificationHandler extends Abs /* * (non-Javadoc) - * + * * @see * com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest * (com.raytheon.uf.common.serialization.comm.IServerRequest) @@ -87,9 +91,28 @@ public class SubscriptionNotificationHandler extends Abs storeAndSend(record, uri); - BaseSubscriptionNotificationResponse response = request.getResponse(); + BaseSubscriptionNotificationResponse response = request + .getResponse(); response.setMessage(request.getMessage()); - response.setSubscription(request.getSubscription()); + + final IBaseSubscriptionHandler subscriptionHandler = response + .getSubscriptionHandler(); + final T requestSubscription = request.getSubscription(); + + if (requestSubscription == null) { + throw new IllegalArgumentException( + "Unable to send a notification for a null subscription!", + new NullPointerException("requestSubscription")); + } + + final T registryVersion = subscriptionHandler + .getByName(requestSubscription.getName()); + + // If the subscription is still in the registry, use that version which + // will reflect any updates that have occurred since the notification + // was sent, otherwise pass along the one provided with the request + response.setSubscription((registryVersion != null) ? registryVersion + : requestSubscription); send(response, uri); diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.feature/feature.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.feature/feature.xml index 7420fa1438..af9645414a 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.feature/feature.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.feature/feature.xml @@ -133,6 +133,13 @@ version="0.0.0" unpack="false"/> + + datesToCrawl = new ArrayList(); Date date = TimeUtil.newImmutableDate(); - long postedFileDelayMilliseconds = TimeUnit.MILLISECONDS - .convert(provider.getPostedFileDelayValue(), - provider.getPostedFileDelayUnits()); + long postedFileDelayMilliseconds = provider + .getPostedFileDelay().getMillis(); if (postedFileDelayMilliseconds > 0) { // Check whether the posted file delay would place us in diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/OPENDAPServiceConfig.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/OPENDAPServiceConfig.xml index dc9ce2dc88..1c895b1050 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/OPENDAPServiceConfig.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/OPENDAPServiceConfig.xml @@ -74,6 +74,7 @@ + diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/harvester/NOMADS-harvester.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/harvester/NOMADS-harvester.xml index 319b9ff0f6..eed51c2d9d 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/harvester/NOMADS-harvester.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/harvester/NOMADS-harvester.xml @@ -41,13 +41,13 @@ /awips2/crawl HHddMMMyyyy ruc - rap32 + rap_f \.das$ \.dds$ help$ - fens_all - cmcens_all - gep_all + fens\d\d\d_ + cmcens[cp]\d\d + ge[cp]\d\d 0 0 12 * * ? diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/cmcensLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/cmcensLevelLookup.xml deleted file mode 100644 index e5cdc29670..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/cmcensLevelLookup.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - 1000.0 - 925.0 - 850.0 - 700.0 - 500.0 - 250.0 - 200.0 - 100.0 - 50.0 - 10.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/fensLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/fensLevelLookup.xml deleted file mode 100644 index e5cdc29670..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/fensLevelLookup.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - 1000.0 - 925.0 - 850.0 - 700.0 - 500.0 - 250.0 - 200.0 - 100.0 - 50.0 - 10.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gensLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gensLevelLookup.xml deleted file mode 100644 index 96a86d0c5d..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gensLevelLookup.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 850.0 - 800.0 - 750.0 - 700.0 - 650.0 - 600.0 - 550.0 - 500.0 - 450.0 - 400.0 - 350.0 - 300.0 - 250.0 - 200.0 - 150.0 - 100.0 - 70.0 - 50.0 - 30.0 - 20.0 - 10.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gens_bcLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gens_bcLevelLookup.xml deleted file mode 100644 index d2aab31231..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gens_bcLevelLookup.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - 1000.0 - 925.0 - 850.0 - 600.0 - 500.0 - 250.0 - 200.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfsLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfsLevelLookup.xml deleted file mode 100644 index dd43090a50..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfsLevelLookup.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 850.0 - 800.0 - 750.0 - 700.0 - 650.0 - 600.0 - 550.0 - 500.0 - 450.0 - 400.0 - 350.0 - 300.0 - 250.0 - 200.0 - 150.0 - 100.0 - 70.0 - 50.0 - 30.0 - 20.0 - 10.0 - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfs_2p5LevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfs_2p5LevelLookup.xml deleted file mode 100644 index 96a86d0c5d..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfs_2p5LevelLookup.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 850.0 - 800.0 - 750.0 - 700.0 - 650.0 - 600.0 - 550.0 - 500.0 - 450.0 - 400.0 - 350.0 - 300.0 - 250.0 - 200.0 - 150.0 - 100.0 - 70.0 - 50.0 - 30.0 - 20.0 - 10.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfs_hdLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfs_hdLevelLookup.xml deleted file mode 100644 index 9c32afbf49..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/gfs_hdLevelLookup.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 875.0 - 850.0 - 825.0 - 800.0 - 775.0 - 750.0 - 725.0 - 700.0 - 675.0 - 650.0 - 625.0 - 600.0 - 575.0 - 550.0 - 525.0 - 500.0 - 475.0 - 450.0 - 425.0 - 400.0 - 375.0 - 350.0 - 325.0 - 300.0 - 275.0 - 250.0 - 225.0 - 200.0 - 175.0 - 150.0 - 125.0 - 100.0 - 70.0 - 50.0 - 30.0 - 20.0 - 10.0 - 7.0 - 5.0 - 3.0 - 2.0 - 1.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/hireswLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/hireswLevelLookup.xml deleted file mode 100644 index ccf28104b4..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/hireswLevelLookup.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - 1000.0 - 925.0 - 850.0 - 700.0 - 600.0 - 500.0 - 400.0 - 300.0 - 250.0 - 200.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/naefs_bcLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/naefs_bcLevelLookup.xml deleted file mode 100644 index eeb016cb52..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/naefs_bcLevelLookup.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - 1000.0 - 925.0 - 850.0 - 700.0 - 500.0 - 250.0 - 200.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/namLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/namLevelLookup.xml deleted file mode 100644 index d1a5b0eef9..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/namLevelLookup.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 875.0 - 850.0 - 825.0 - 800.0 - 775.0 - 750.0 - 725.0 - 700.0 - 675.0 - 650.0 - 625.0 - 600.0 - 575.0 - 550.0 - 525.0 - 500.0 - 475.0 - 450.0 - 425.0 - 400.0 - 375.0 - 350.0 - 325.0 - 300.0 - 275.0 - 250.0 - 225.0 - 200.0 - 175.0 - 150.0 - 125.0 - 100.0 - 75.0 - 50.0 - 20.0 - 10.0 - 5.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/ofsLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/ofsLevelLookup.xml deleted file mode 100644 index fb041d3a97..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/ofsLevelLookup.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 6000.0 - 5500.0 - 5000.0 - 4500.0 - 4000.0 - 3500.0 - 3000.0 - 2500.0 - 2000.0 - 1500.0 - 1000.0 - 950.0 - 900.0 - 850.0 - 800.0 - 750.0 - 700.0 - 650.0 - 600.0 - 550.0 - 500.0 - 450.0 - 400.0 - 350.0 - 300.0 - 250.0 - 200.0 - 150.0 - 100.0 - 90.0 - 80.0 - 70.0 - 60.0 - 50.0 - 30.0 - 20.0 - 10.0 - 6.0 - 3.0 - 0.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rapLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rapLevelLookup.xml deleted file mode 100644 index 9996d3048a..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rapLevelLookup.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 875.0 - 850.0 - 825.0 - 800.0 - 775.0 - 750.0 - 725.0 - 700.0 - 675.0 - 650.0 - 625.0 - 600.0 - 575.0 - 550.0 - 525.0 - 500.0 - 475.0 - 450.0 - 425.0 - 400.0 - 375.0 - 350.0 - 325.0 - 300.0 - 275.0 - 250.0 - 225.0 - 200.0 - 175.0 - 150.0 - 125.0 - 100.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rucLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rucLevelLookup.xml deleted file mode 100644 index 9996d3048a..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/rucLevelLookup.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 875.0 - 850.0 - 825.0 - 800.0 - 775.0 - 750.0 - 725.0 - 700.0 - 675.0 - 650.0 - 625.0 - 600.0 - 575.0 - 550.0 - 525.0 - 500.0 - 475.0 - 450.0 - 425.0 - 400.0 - 375.0 - 350.0 - 325.0 - 300.0 - 275.0 - 250.0 - 225.0 - 200.0 - 175.0 - 150.0 - 125.0 - 100.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/srefLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/srefLevelLookup.xml deleted file mode 100644 index 892534c4a7..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/srefLevelLookup.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - 1000.0 - 975.0 - 950.0 - 925.0 - 900.0 - 875.0 - 850.0 - 825.0 - 800.0 - 775.0 - 750.0 - 725.0 - 700.0 - 675.0 - 650.0 - 625.0 - 600.0 - 575.0 - 550.0 - 525.0 - 500.0 - 475.0 - 450.0 - 425.0 - 400.0 - 375.0 - 350.0 - 325.0 - 300.0 - 275.0 - 250.0 - 225.0 - 200.0 - 175.0 - 150.0 - 125.0 - 100.0 - 75.0 - 50.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/sref_bcLevelLookup.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/sref_bcLevelLookup.xml deleted file mode 100644 index e04f191f0b..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/utility/common_static/base/datadelivery/lookups/sref_bcLevelLookup.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - 1000.0 - 850.0 - 700.0 - 500.0 - 250.0 - diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/metadata/adapters/GridMetadataAdapter.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/metadata/adapters/GridMetadataAdapter.java index 3e8f524583..7649d934b3 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/metadata/adapters/GridMetadataAdapter.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/metadata/adapters/GridMetadataAdapter.java @@ -20,6 +20,8 @@ package com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import com.raytheon.edex.util.Util; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; @@ -60,11 +62,18 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter { Level[] levels = getLevels(attXML); int size = levels.length; + List ensembles = null; + if (attXML.getEnsemble() != null && attXML.getEnsemble().hasSelection()) { + ensembles = attXML.getEnsemble().getSelectedMembers(); + size *= ensembles.size(); + } else { + ensembles = Arrays.asList((String) null); + } + if (attXML.getTime().getSelectedTimeIndices() != null) { if (levels.length > 1 || attXML.getTime().getSelectedTimeIndices().size() > 1) { - size = levels.length - * attXML.getTime().getSelectedTimeIndices().size(); + size *= attXML.getTime().getSelectedTimeIndices().size(); } } @@ -80,20 +89,21 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter { } if (attXML.getTime().getSelectedTimeIndices() != null) { - - for (int i = 0; i < attXML.getTime().getSelectedTimeIndices() - .size(); i++) { - for (int j = 0; j < levels.length; j++) { - int bin = (levels.length * i) + j; - pdos[bin] = populateGridRecord(attXML.getSubName(), - attXML.getParameter(), - levels[j], gridCoverage); + int bin = 0; + for (String ensemble : ensembles) { + for (int i = 0; i < attXML.getTime().getSelectedTimeIndices() + .size(); i++) { + for (int j = 0; j < levels.length; j++) { + pdos[bin++] = populateGridRecord(attXML.getSubName(), + attXML.getParameter(), levels[j], ensemble, + gridCoverage); + } } } } else { pdos[0] = populateGridRecord(attXML.getSubName(), - attXML.getParameter(), levels[0], + attXML.getParameter(), levels[0], ensembles.get(0), gridCoverage); } @@ -108,10 +118,9 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter { * @return */ private GridRecord populateGridRecord(String name, Parameter parm, - Level level, - GridCoverage gridCoverage) { + Level level, String ensembleId, GridCoverage gridCoverage) { return ResponseProcessingUtilities.getGridRecord(name, parm, level, - gridCoverage); + ensembleId, gridCoverage); } /** diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPMetaDataParser.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPMetaDataParser.java index af804b230a..03457fd269 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPMetaDataParser.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPMetaDataParser.java @@ -37,6 +37,7 @@ import com.raytheon.uf.common.datadelivery.registry.DataSet; import com.raytheon.uf.common.datadelivery.registry.DataSetMetaData; import com.raytheon.uf.common.datadelivery.registry.DataType; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; +import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet; import com.raytheon.uf.common.datadelivery.registry.GriddedDataSetMetaData; import com.raytheon.uf.common.datadelivery.registry.Levels; import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSet; @@ -88,6 +89,8 @@ import dods.dap.DAS; * Dec 12, 2012 supplement dhladky Restored operation of ensembles. * Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes. * Jan 08, 2013 dhladky Performance enhancements, specific model fixes. + * Jan 18, 2013 1513 dhladky Level look up improvements. + * Jan 24, 2013 1527 dhladky Changed 0DEG to FRZ * * * @@ -134,8 +137,10 @@ class OpenDAPMetaDataParser extends MetaDataParser { // create new default lookups if (levelType.equals(LevelType.MB) || levelType.equals(LevelType.SEAB)) { + + List levelList = OpenDAPParseUtility.getInstance().parseLevels(gdsmd.getUrl(), serviceConfig.getConstantValue("LEV")); LookupManager.getInstance().modifyLevelLookups( - collectionName, dz, levMin, levMax); + collectionName, dz, levMin, levMax, levelList); } } @@ -179,7 +184,8 @@ class OpenDAPMetaDataParser extends MetaDataParser { * @param dataDateFormat * @return */ - private Map getParameters(DAS das, DataSet dataSet, + private Map getParameters(DAS das, + GriddedDataSet dataSet, GriddedDataSetMetaData gdsmd, Link link, Collection collection, String dataDateFormat) { @@ -336,7 +342,8 @@ class OpenDAPMetaDataParser extends MetaDataParser { if (das.getAttributeTable(ens) != null) { try { AttributeTable at = das.getAttributeTable(ens); - gdsmd.setEnsemble(OpenDAPParseUtility.getInstance().parseEnsemble(at)); + dataSet.setEnsemble(OpenDAPParseUtility.getInstance() + .parseEnsemble(at)); } catch (Exception en) { logParsingException(ens, "Ensemble", collectionName, url); } @@ -413,12 +420,6 @@ class OpenDAPMetaDataParser extends MetaDataParser { parm.setLevels(getLevels(type, collectionName, gdsmd, dz, levMin, levMax)); parm.addLevelType(type); - - // set if an ensemble member - if (gdsmd.getEnsemble() != null) { - parm.setEnsemble(gdsmd.getEnsemble().getSize()); - } - parameters.put(name, parm); } catch (Exception le) { @@ -493,6 +494,11 @@ class OpenDAPMetaDataParser extends MetaDataParser { type.addLayer(new Double(10).doubleValue()); type.setUnit(serviceConfig.getConstantValue("METER")); } + // FRZ freezing level, catches one's with on the end of the param name + // hgt0c etc + else if (param.getProviderName().endsWith(LevelType.FRZ.getLevelType())) { + type = new DataLevelType(LevelType.FRZ); + } // Really special cases presented by NOMADS data sets if (type == null) { @@ -572,8 +578,8 @@ class OpenDAPMetaDataParser extends MetaDataParser { type = new DataLevelType(LevelType.MSL); } else if (w1.equals(LevelType.EA.getLevelType())) { type = new DataLevelType(LevelType.EA); - } else if (w1.equals(LevelType.ODEG.getLevelType())) { - type = new DataLevelType(LevelType.ODEG); + } else if (w1.equals(LevelType.FRZ.getLevelType())) { + type = new DataLevelType(LevelType.FRZ); } else if (w1.equals(LevelType.LCY.getLevelType())) { type = new DataLevelType(LevelType.LCY); } else if (w1.equals(LevelType.MCY.getLevelType())) { @@ -656,12 +662,12 @@ class OpenDAPMetaDataParser extends MetaDataParser { } DAS das = (DAS) link.getLinks().get(DAP_TYPE.DAS.getDapType()); - dataSet.setParameters(getParameters(das, dataSet, gdsmd, link, - collection, dataDateFormat)); - + // set url first, used for level lookups gdsmd.setUrl(link.getUrl().replace( serviceConfig.getConstantValue("META_DATA_SUFFIX"), serviceConfig.getConstantValue("BLANK"))); + dataSet.setParameters(getParameters(das, dataSet, gdsmd, link, + collection, dataDateFormat)); Time dataSetTime = gdsmd.getTime(); if (dataSetTime == null) { throw new IllegalStateException( diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPParseUtility.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPParseUtility.java index 37c865d6c4..9ce0350fa0 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPParseUtility.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPParseUtility.java @@ -21,8 +21,13 @@ import com.raytheon.uf.common.datadelivery.retrieval.xml.UnitLookup; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.edex.datadelivery.retrieval.util.ConnectionUtil; import dods.dap.AttributeTable; +import dods.dap.DArray; +import dods.dap.DConnect; +import dods.dap.DataDDS; +import dods.dap.PrimitiveVector; /** * Constants for working with OpenDAP. This class should remain package-private, @@ -43,15 +48,18 @@ import dods.dap.AttributeTable; * Nov 09, 2012 1163 dhladky Made pre-load for service config * Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects. * Jan 08, 2013 1466 dhladky NCOM dataset name parsing fix. + * Jan 18, 2013 1513 dhladky Level Lookup improvements. * * * @author dhladky * @version 1.0 */ -final class OpenDAPParseUtility { +public final class OpenDAPParseUtility { private static final Pattern QUOTES_PATTERN = Pattern.compile("\""); + private static final Pattern COMMA_PATTERN = Pattern.compile(","); + /** Singleton instance of this class */ private static OpenDAPParseUtility instance = null; @@ -252,35 +260,16 @@ final class OpenDAPParseUtility { */ public Ensemble parseEnsemble(AttributeTable table) { - String stime = serviceConfig.getConstantValue("TIMEINIT"); - String slength = serviceConfig.getConstantValue("LENGTH"); String sname = serviceConfig.getConstantValue("NAME"); - int size = new Integer(trim(table.getAttribute( - serviceConfig.getConstantValue("SIZE")).getValueAt(0))) - .intValue(); - String name = null; - String length = null; - String tinit = null; - - if (table.getAttribute(slength) != null) { - length = table.getAttribute(slength).getValueAt(0); - } + Ensemble ens = new Ensemble(); if (table.getAttribute(sname) != null) { - name = table.getAttribute(sname).getValueAt(0); + String name = trim(table.getAttribute(sname).getValueAt(0)); + String[] members = COMMA_PATTERN.split(name); + ens.setMembers(Arrays.asList(members)); } - - if (table.getAttribute(stime) != null) { - tinit = table.getAttribute(stime).getValueAt(0); - } - - Ensemble ens = new Ensemble(); - ens.setSize(size); - ens.setLength(length); - ens.setName(name); - ens.setInit(tinit); - return ens; + } /** @@ -353,7 +342,35 @@ final class OpenDAPParseUtility { return QUOTES_PATTERN.matcher(val).replaceAll( serviceConfig.getConstantValue("BLANK")); } - + /** + * Parse out the levels from the dods + * @param url + * @param lev + * @return + */ + public List parseLevels(String url, String lev) { + + List levels = null; + + try { + DConnect connect = ConnectionUtil.getDConnect(url + "?" + lev); + DataDDS data = connect.getData(null); + DArray array = (DArray) data.getVariable(lev); + PrimitiveVector pm = array.getPrimitiveVector(); + double[] values = (double[]) pm.getInternalStorage(); + levels = new ArrayList(); + for (double value : values) { + levels.add(value); + } + + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, "Error downloading/parsing levels: " + + url, e); + } + + return levels; + + } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRequestBuilder.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRequestBuilder.java index 2aa40d5e24..f917f94bc0 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRequestBuilder.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRequestBuilder.java @@ -22,6 +22,7 @@ package com.raytheon.uf.edex.datadelivery.retrieval.opendap; import com.google.common.annotations.VisibleForTesting; import com.raytheon.uf.common.datadelivery.registry.Coverage; +import com.raytheon.uf.common.datadelivery.registry.Ensemble; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; import com.raytheon.uf.common.datadelivery.registry.Levels; import com.raytheon.uf.common.datadelivery.registry.Parameter; @@ -216,17 +217,17 @@ class OpenDAPRequestBuilder extends RequestBuilder { */ public String processEnsemble() { - StringBuilder buf = new StringBuilder(); - - if (getRetrievalAttribute().getParameter().getEnsemble() != null) { - buf.append("[" - + (getRetrievalAttribute().getParameter().getEnsemble() - 1) - + "]"); + if (getRetrievalAttribute().getEnsemble() != null) { + Ensemble e = getRetrievalAttribute().getEnsemble(); + int[] range = e.getSelectedRange(); + if (range[0] == range[1]) { + return "[" + range[0] + "]"; + } else { + return "[" + range[0] + ":" + range[1] + "]"; + } } else { - buf.append(""); + return ""; } - - return buf.toString(); } @Override diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRetrievalGenerator.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRetrievalGenerator.java index 40fbe7ffdb..f05db83d6e 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRetrievalGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/opendap/OpenDAPRetrievalGenerator.java @@ -22,14 +22,15 @@ package com.raytheon.uf.edex.datadelivery.retrieval.opendap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import com.google.common.annotations.VisibleForTesting; import com.raytheon.uf.common.datadelivery.registry.Coverage; import com.raytheon.uf.common.datadelivery.registry.DataSet; import com.raytheon.uf.common.datadelivery.registry.DataSetMetaData; +import com.raytheon.uf.common.datadelivery.registry.Ensemble; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; import com.raytheon.uf.common.datadelivery.registry.GriddedDataSetMetaData; import com.raytheon.uf.common.datadelivery.registry.Levels; @@ -265,13 +266,14 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { * @param parm * @return */ - protected HashMap> getGridDuplicates( + protected Map> getGridDuplicates( String name, - Parameter parm, ArrayList times, ArrayList levels, + Parameter parm, List times, List levels, + List ensembleMembers, GriddedCoverage cov) { return RetrievalGeneratorUtilities.findGridDuplicates(name, times, - levels, + levels, ensembleMembers, parm, cov.getRequestGridCoverage()); } @@ -319,6 +321,13 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { return Collections.emptyList(); } + List ensembles = null; + if (sub.getEnsemble() == null) { + ensembles = Arrays.asList((Ensemble) null); + } else { + ensembles = sub.getEnsemble().split(1); + } + for (List timeSequence : subTime.getTimeSequences(sfactor)) { for (Parameter param : sub.getParameter()) { @@ -332,9 +341,11 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { sub.getTime()); for (Time time : times) { - Retrieval retrieval = getRetrieval(sub, bundle, - param, paramLevels, time); - retrievals.add(retrieval); + for (Ensemble ensemble : ensembles) { + Retrieval retrieval = getRetrieval(sub, bundle, + param, paramLevels, time, ensemble); + retrievals.add(retrieval); + } } } else { @@ -350,9 +361,12 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { // and time for (Time time : times) { for (Levels level : levels) { - Retrieval retrieval = getRetrieval(sub, - bundle, param, level, time); - retrievals.add(retrieval); + for (Ensemble ensemble : ensembles) { + Retrieval retrieval = getRetrieval(sub, + bundle, param, level, time, + ensemble); + retrievals.add(retrieval); + } } } } @@ -375,7 +389,7 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { * @return */ private Retrieval getRetrieval(Subscription sub, SubscriptionBundle bundle, - Parameter param, Levels level, Time time) { + Parameter param, Levels level, Time time, Ensemble ensemble) { Retrieval retrieval = new Retrieval(); retrieval.setSubscriptionName(sub.getName()); @@ -404,6 +418,7 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { lparam.setLevels(level); att.setTime(time); att.setParameter(lparam); + att.setEnsemble(ensemble); att.setSubName(retrieval.getSubscriptionName()); att.setPlugin(pt.getPlugin()); att.setProvider(sub.getProvider()); @@ -488,7 +503,6 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { param.setBaseType(origParm.getBaseType()); param.setDataType(origParm.getDataType()); param.setDefinition(origParm.getDefinition()); - param.setEnsemble(origParm.getEnsemble()); param.setFillValue(origParm.getFillValue()); param.setLevelType(origParm.getLevelType()); param.setMissingValue(origParm.getMissingValue()); @@ -536,6 +550,13 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { int sfactor = getSizingFactor(getDimensionalSize(sub.getCoverage())); + List ensembles = null; + if (sub.getEnsemble() != null && sub.getEnsemble().hasSelection()) { + ensembles = sub.getEnsemble().getSelectedMembers(); + } else { + ensembles = Arrays.asList((String) null); + } + for (List timeSequence : sub.getTime().getTimeSequences( sfactor)) { @@ -557,14 +578,14 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { ArrayList levels = ResponseProcessingUtilities .getOpenDAPGridLevels(param.getLevels()); - HashMap> dups = getGridDuplicates( + Map> dups = getGridDuplicates( sub.getName(), - param, times, levels, + param, times, levels, ensembles, (GriddedCoverage) sub.getCoverage()); for (int i = 0; i < times.size(); i++) { DataTime dtime = times.get(i); - ArrayList levDups = dups.get(dtime); + List levDups = dups.get(dtime); if (levDups != null) { // single level, remove the time @@ -594,14 +615,14 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { .getOpenDAPGridLevels(level); } - HashMap> dups = getGridDuplicates( - sub.getName(), - param, times, plevels, + Map> dups = getGridDuplicates( + sub.getName(), param, times, plevels, + ensembles, ((GriddedCoverage) sub.getCoverage())); for (int i = 0; i < times.size(); i++) { DataTime dtime = times.get(i); - ArrayList levDups = dups.get(dtime); + List levDups = dups.get(dtime); if (levDups != null) { diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/response/OpenDAPTranslator.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/response/OpenDAPTranslator.java index c3c790be13..75b4c933a0 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/response/OpenDAPTranslator.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/response/OpenDAPTranslator.java @@ -23,6 +23,7 @@ package com.raytheon.uf.edex.datadelivery.retrieval.response; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; +import java.util.List; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute; @@ -149,33 +150,41 @@ public class OpenDAPTranslator extends RetrievalTranslator { PrimitiveVector pm = darray.getPrimitiveVector(); float[] values = (float[]) pm.getInternalStorage(); + List ensembles = null; + if (attXML.getEnsemble() != null && attXML.getEnsemble().hasSelection()) { + ensembles = attXML.getEnsemble().getSelectedMembers(); + } else { + ensembles = Arrays.asList((String) null); + } + // time dependencies int start = 0; - PluginDataObject[] records = new PluginDataObject[numLevels * numTimes]; + PluginDataObject[] records = new PluginDataObject[numLevels * numTimes + * ensembles.size()]; - for (int i = 0; i < times.size(); i++) { + int bin = 0; + for (int i = 0; i < ensembles.size(); i++) { + for (DataTime dataTime : times) { + for (int j = 0; j < numLevels; j++) { + PluginDataObject record = getPdo(bin); + record.setDataTime(dataTime); + record.constructDataURI(); - DataTime dataTime = times.get(i); + int end = start + gridSize; - for (int j = 0; j < numLevels; j++) { - int bin = (numLevels * i) + j; - PluginDataObject record = getPdo(bin); - record.setDataTime(dataTime); - record.constructDataURI(); + float[] subValues = Arrays.copyOfRange(values, start, end); - int end = start + gridSize; + subValues = GridMetadataAdapter.adjustGrid(nx, ny, + subValues, Float.parseFloat(attXML.getParameter() + .getMissingValue()), true); - float[] subValues = Arrays.copyOfRange(values, start, end); - - subValues = GridMetadataAdapter.adjustGrid(nx, ny, subValues, - Float.parseFloat(attXML.getParameter() - .getMissingValue()), true); - - record.setMessageData(subValues); - record.setOverwriteAllowed(true); - records[bin] = record; - statusHandler.info("Creating record: " + record.getDataURI()); - start = end; + record.setMessageData(subValues); + record.setOverwriteAllowed(true); + records[bin++] = record; + statusHandler.info("Creating record: " + + record.getDataURI()); + start = end; + } } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/ResponseProcessingUtilities.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/ResponseProcessingUtilities.java index bdd987f7b6..1250b30a4f 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/ResponseProcessingUtilities.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/ResponseProcessingUtilities.java @@ -61,7 +61,7 @@ public class ResponseProcessingUtilities { .getHandler(ResponseProcessingUtilities.class); public static GridRecord getGridRecord(String name, Parameter parm, - Level level, + Level level, String ensembleId, GridCoverage gridCoverage) { com.raytheon.uf.common.parameter.Parameter parameter = new com.raytheon.uf.common.parameter.Parameter(); @@ -75,7 +75,7 @@ public class ResponseProcessingUtilities { record.setLevel(level); record.setParameter(parameter); record.setDatasetId(name); - + record.setEnsembleId(ensembleId); return record; } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/RetrievalGeneratorUtilities.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/RetrievalGeneratorUtilities.java index 31da7a43aa..09f717150a 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/RetrievalGeneratorUtilities.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/src/com/raytheon/uf/edex/datadelivery/retrieval/util/RetrievalGeneratorUtilities.java @@ -21,6 +21,8 @@ package com.raytheon.uf.edex.datadelivery.retrieval.util; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; import com.raytheon.uf.common.datadelivery.registry.Parameter; import com.raytheon.uf.common.dataplugin.PluginException; @@ -87,35 +89,39 @@ public class RetrievalGeneratorUtilities { * @param cov * @return */ - public static HashMap> findGridDuplicates( - String name, - ArrayList times, ArrayList levels, Parameter parm, + public static Map> findGridDuplicates(String name, + List times, List levels, + List ensembleMembers, Parameter parm, GridCoverage cov) { - HashMap> dups = new HashMap>(); + HashMap> dups = new HashMap>(); for (DataTime time : times) { - ArrayList levDups = dups.get(time); + List levDups = dups.get(time); if (levDups == null) { levDups = new ArrayList(); } for (Level level : levels) { - try { + for (String ensembleMember : ensembleMembers) { + try { - GridRecord rec = ResponseProcessingUtilities.getGridRecord( - name, parm, level, cov); - rec.setDataTime(time); - rec.constructDataURI(); - boolean isDup = findDuplicateUri(rec.getDataURI(), "grid"); - if (isDup) { - levDups.add(level); + GridRecord rec = ResponseProcessingUtilities + .getGridRecord(name, parm, level, + ensembleMember, cov); + rec.setDataTime(time); + rec.constructDataURI(); + boolean isDup = findDuplicateUri(rec.getDataURI(), + "grid"); + if (isDup) { + levDups.add(level); + } + } catch (PluginException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); } - } catch (PluginException e) { - statusHandler.handle(Priority.PROBLEM, - e.getLocalizedMessage(), e); } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/utility/edex_static/base/stats/retrievalProcessStats.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/utility/edex_static/base/stats/retrievalProcessStats.xml new file mode 100644 index 0000000000..2759dde1d3 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/utility/edex_static/base/stats/retrievalProcessStats.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.service/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.datadelivery.service/META-INF/MANIFEST.MF index bec6b2084d..ae74a38fbe 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.service/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.service/META-INF/MANIFEST.MF @@ -21,4 +21,5 @@ Require-Bundle: com.raytheon.uf.common.auth;bundle-version="1.12.1174", com.raytheon.uf.common.registry.event;bundle-version="1.0.0", com.raytheon.uf.common.event;bundle-version="1.0.0", com.google.guava;bundle-version="1.0.0", - com.raytheon.uf.common.datadelivery.event;bundle-version="1.0.0" + com.raytheon.uf.common.datadelivery.event;bundle-version="1.0.0", + com.raytheon.uf.common.datadelivery.service;bundle-version="1.0.0" diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.service/res/spring/datadelivery-request.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.service/res/spring/datadelivery-service-handlers.xml similarity index 65% rename from edexOsgi/com.raytheon.uf.edex.datadelivery.service/res/spring/datadelivery-request.xml rename to edexOsgi/com.raytheon.uf.edex.datadelivery.service/res/spring/datadelivery-service-handlers.xml index c9532a124d..3cd1b2f13d 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.service/res/spring/datadelivery-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.service/res/spring/datadelivery-service-handlers.xml @@ -12,13 +12,24 @@
- + + + + - + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.service/src/com/raytheon/uf/edex/datadelivery/service/services/GroupDefinitionServiceHandler.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.service/src/com/raytheon/uf/edex/datadelivery/service/services/GroupDefinitionServiceHandler.java new file mode 100644 index 0000000000..c2b9abb06c --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.service/src/com/raytheon/uf/edex/datadelivery/service/services/GroupDefinitionServiceHandler.java @@ -0,0 +1,131 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.datadelivery.service.services; + +import java.util.List; + +import com.raytheon.uf.common.auth.exception.AuthorizationException; +import com.raytheon.uf.common.auth.user.IUser; +import com.raytheon.uf.common.datadelivery.registry.GroupDefinition; +import com.raytheon.uf.common.datadelivery.registry.GroupDefinitionServiceRequest; +import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; +import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler; +import com.raytheon.uf.common.datadelivery.service.IGroupDefinitionService; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; +import com.raytheon.uf.common.registry.handler.RegistryHandlerException; +import com.raytheon.uf.common.util.CollectionUtil; +import com.raytheon.uf.edex.auth.req.AbstractPrivilegedRequestHandler; +import com.raytheon.uf.edex.auth.resp.AuthorizationResponse; + +/** + * Handles request from the {@link IGroupDefinitionService}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2013 1441       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class GroupDefinitionServiceHandler extends + AbstractPrivilegedRequestHandler { + + private final ISubscriptionNotificationService notificationService; + + /** + * Constructor. + * + * @param notificationService + * the subscription notification service + */ + public GroupDefinitionServiceHandler( + ISubscriptionNotificationService notificationService) { + this.notificationService = notificationService; + } + + /** + * {@inheritDoc} + */ + @Override + public Object handleRequest(GroupDefinitionServiceRequest request) + throws Exception { + final IUser user = request.getUser(); + switch (request.getType()) { + case DELETE: + handleDelete(request.getGroup(), user); + break; + } + return null; + } + + /** + * Handles the delete of a group. First it updates any subscriptions in the + * group to not have a group, and then deletes the actual group. + * + * @param user + * + * @param groupDefinition + * @return + * @throws RegistryHandlerException + */ + private void handleDelete(GroupDefinition group, IUser user) + throws RegistryHandlerException { + + ISubscriptionHandler handler = DataDeliveryHandlers + .getSubscriptionHandler(); + List subsForGroup = handler.getByGroupName(group + .getGroupName()); + if (!CollectionUtil.isNullOrEmpty(subsForGroup)) { + for (Subscription sub : subsForGroup) { + sub.setGroupName(GroupDefinition.NO_GROUP); + handler.update(sub); + + // TODO: Would be nice to use a subset of the + // SubscriptionService functionality here so we didn't have to + // manually send the subscription updated notification + String username = user != null ? user.uniqueId().toString() + : "none"; + notificationService.sendUpdatedSubscriptionNotification(sub, + username); + } + } + + DataDeliveryHandlers.getGroupDefinitionHandler().delete(group); + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorizationResponse authorized(IUser user, + GroupDefinitionServiceRequest request) + throws AuthorizationException { + return new AuthorizationResponse(true); + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.log/src/com/raytheon/uf/edex/log/EdexLogHandler.java b/edexOsgi/com.raytheon.uf.edex.log/src/com/raytheon/uf/edex/log/EdexLogHandler.java index a4b472d85e..54a7d64a16 100644 --- a/edexOsgi/com.raytheon.uf.edex.log/src/com/raytheon/uf/edex/log/EdexLogHandler.java +++ b/edexOsgi/com.raytheon.uf.edex.log/src/com/raytheon/uf/edex/log/EdexLogHandler.java @@ -98,11 +98,11 @@ public class EdexLogHandler implements IUFStatusHandler { */ @Override public void handle(UFStatus status) { - handle(status, this.category); - } + handle(status, this.category); + } - @Override - public void handle(UFStatus status, String category) { + @Override + public void handle(UFStatus status, String category) { Priority p = status.getPriority(); String statusMsg = status.getMessage(); if (category != null) { @@ -154,11 +154,14 @@ public class EdexLogHandler implements IUFStatusHandler { @Override public void handle(Priority p, String msg) { - handle(p, this.category, msg); - } + handle(p, this.category, msg); + } - @Override - public void handle(Priority p, String category, String msg) { + @Override + public void handle(Priority p, String category, String msg) { + // msg has been null if someone does e.getLocalizedMessage() + // and it is null which causes null pointer exception + msg = String.valueOf(msg); if (category != null) { StringBuilder sb = new StringBuilder(msg.length() + 64); sb.append(category); @@ -197,13 +200,13 @@ public class EdexLogHandler implements IUFStatusHandler { @Override public void handle(Priority p, String msg, Throwable t) { - handle(p, category, msg, t); - } + handle(p, category, msg, t); + } - @Override - public void handle(Priority p, String category, String msg, Throwable t) { - // msg has been null if someone does e.getLocalizedMessage() - // and it is null which causes null pointer exception + @Override + public void handle(Priority p, String category, String msg, Throwable t) { + // msg has been null if someone does e.getLocalizedMessage() + // and it is null which causes null pointer exception msg = String.valueOf(msg); if (category != null) { StringBuilder sb = new StringBuilder(msg.length() + 64); @@ -249,21 +252,21 @@ public class EdexLogHandler implements IUFStatusHandler { } @Override - public void debug(String category, String message) { - if (this.clazzLogger.isDebugEnabled()) { - handle(Priority.DEBUG, category, message); - } - } + public void debug(String category, String message) { + if (this.clazzLogger.isDebugEnabled()) { + handle(Priority.DEBUG, category, message); + } + } - @Override + @Override public void info(String message) { handle(Priority.INFO, message); } - @Override - public void info(String category, String message) { - handle(Priority.INFO, category, message); - } + @Override + public void info(String category, String message) { + handle(Priority.INFO, category, message); + } @Override public void warn(String message) { @@ -271,38 +274,38 @@ public class EdexLogHandler implements IUFStatusHandler { } @Override - public void warn(String category, String message) { - handle(Priority.WARN, category, message); - } + public void warn(String category, String message) { + handle(Priority.WARN, category, message); + } - @Override + @Override public void error(String message) { handle(Priority.ERROR, message); } @Override - public void error(String category, String message) { - handle(Priority.ERROR, category, message); - } + public void error(String category, String message) { + handle(Priority.ERROR, category, message); + } - @Override + @Override public void error(String message, Throwable throwable) { handle(Priority.ERROR, message, throwable); } @Override - public void error(String category, String message, Throwable throwable) { - handle(Priority.ERROR, category, message, throwable); - } + public void error(String category, String message, Throwable throwable) { + handle(Priority.ERROR, category, message, throwable); + } - @Override + @Override public void fatal(String message, Throwable throwable) { handle(Priority.FATAL, message, throwable); } - @Override - public void fatal(String category, String message, Throwable throwable) { - handle(Priority.FATAL, category, message, throwable); - } + @Override + public void fatal(String category, String message, Throwable throwable) { + handle(Priority.FATAL, category, message, throwable); + } } diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/ArealQpeGenSrv.java b/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/ArealQpeGenSrv.java index a6411a4ec1..29e73a95a8 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/ArealQpeGenSrv.java +++ b/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/ArealQpeGenSrv.java @@ -70,6 +70,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jan 26, 2011 snaples Initial creation + * Jan 10, 2013 1448 bgonzale Added app context check in processArealQpe(). * * * @@ -209,6 +210,9 @@ public class ArealQpeGenSrv { private SimpleDateFormat fdf = new SimpleDateFormat("yyyyMMddHH"); public Object processArealQpe() { + if (!AppsDefaults.getInstance().setAppContext(this)) { + return null; + } // Check to see if we need to run String gen = appsDefaults.getToken("mpe_generate_areal_qpe"); diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeLightningSrv.java b/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeLightningSrv.java index 98653ac91e..f1e80fe538 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeLightningSrv.java +++ b/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeLightningSrv.java @@ -37,6 +37,7 @@ import com.raytheon.uf.common.datastorage.DataStoreFactory; import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.common.datastorage.StorageException; import com.raytheon.uf.common.hydro.spatial.HRAP; +import com.raytheon.uf.common.ohd.AppsDefaults; import com.raytheon.uf.edex.core.EdexException; import com.raytheon.uf.edex.core.props.EnvProperties; import com.raytheon.uf.edex.core.props.PropertiesFactory; @@ -54,6 +55,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jan 06, 2011 5951 jnjanga Initial creation + * Jan 10, 2013 1448 bgonzale Added app context check in runOnSchedule(). * * * @@ -218,6 +220,9 @@ public class MpeLightningSrv { * @throws EdexException */ public void runOnSchedule() throws EdexException { + if (!AppsDefaults.getInstance().setAppContext(this)) { + return; + } QueryResultRow[] rows = getMostRecentStrikes(); ifhsInsertMostRecentStrikes(rows); } diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeRUCFreezingLevel.java b/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeRUCFreezingLevel.java index 954bae7509..9e525fef4e 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeRUCFreezingLevel.java +++ b/edexOsgi/com.raytheon.uf.edex.ohd/src/com/raytheon/uf/edex/ohd/pproc/MpeRUCFreezingLevel.java @@ -55,24 +55,24 @@ import com.raytheon.uf.edex.core.props.PropertiesFactory; import com.raytheon.uf.edex.dat.utils.FreezingLevel; import com.vividsolutions.jts.geom.Coordinate; +/** + * MPE RUC calculator + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#  Engineer    Description
+ * ------------ -------- --------- --------------------------
+ * Nov 19, 2011          dhladky    Initial Creation.
+ * Oct 09, 2012 15168    wkwock     Fix incorrect values.
+ * Jan 10, 2013 1448     bgonzale   Made methods that are used internally private.
+ * 
+ * 
+ * + * @author dhladky + * @version 1.0 + */ public class MpeRUCFreezingLevel { - /** - * MPE RUC calculator - * - *
-     * SOFTWARE HISTORY
-     * Date         Ticket#  Engineer    Description
-     * ------------ -------- --------- --------------------------
-     * Nov 19, 2011          dhladky    Initial Creation.
-     * Oct 09, 2012 15168    wkwock     Fix incorrect values.
-     * 
-     * 
- * - * @author dhladky - * @version 1.0 - */ - private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(MpeRUCFreezingLevel.class); @@ -441,7 +441,7 @@ public class MpeRUCFreezingLevel { * * @return */ - public String getAbsoluteTempFileName(int forecastHour, String modelName) { + private String getAbsoluteTempFileName(int forecastHour, String modelName) { return modelOutputFilePath + File.separatorChar + modelName + forecastHour + "zFreezingLevel" + ".bin"; } @@ -451,7 +451,7 @@ public class MpeRUCFreezingLevel { * * @return */ - public String getAbsoluteOutFileName(Date date, String site) { + private String getAbsoluteOutFileName(Date date, String site) { return modelOutputFilePath + File.separatorChar + "freezing_1_" + site + "_point_" + getFormattedDate(date); } @@ -461,7 +461,7 @@ public class MpeRUCFreezingLevel { * * @param FreezingLevelXML */ - public void writeFreezingLevelTemp(FreezingLevelXML freezingLevel, + private void writeFreezingLevelTemp(FreezingLevelXML freezingLevel, String modelName) { try { diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.cwa/utility/edex_static/base/distribution/cwa.xml b/edexOsgi/com.raytheon.uf.edex.plugin.cwa/utility/edex_static/base/distribution/cwa.xml index 3510a85960..a6fdefdf81 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.cwa/utility/edex_static/base/distribution/cwa.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.cwa/utility/edex_static/base/distribution/cwa.xml @@ -20,5 +20,5 @@ --> ^FAAK2.* - ^FAUS2.* + ^FAUS2[0-6].* diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml index 7e563040f4..5ac1430bef 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml @@ -14,8 +14,8 @@
- - + + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java index 74dc7d497c..9b743dc7de 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java @@ -31,15 +31,19 @@ import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.regex.Pattern; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; import com.raytheon.edex.msg.DataURINotificationMessage; import com.raytheon.edex.plugin.radar.dao.RadarStationDao; import com.raytheon.edex.urifilter.URIFilter; import com.raytheon.edex.urifilter.URIGenerateMessage; +import com.raytheon.uf.common.dataplugin.ffmp.FFMPAggregateRecord; import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData; import com.raytheon.uf.common.dataplugin.ffmp.FFMPDataContainer; import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord; @@ -79,6 +83,7 @@ import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.common.util.FileUtil; import com.raytheon.uf.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.props.PropertiesFactory; @@ -105,6 +110,7 @@ import com.raytheon.uf.edex.plugin.ffmp.common.FFTIProcessor; * 06/21/2009 2521 dhladky Initial Creation. * 02/03/2011 6500 cjeanbap Fixed NullPointerException. * 07/31/2011 578 dhladky FFTI modifications + * 01/27/13 1478 D. Hladky Added creation of full cache records to help read write stress on NAS * * * @author dhladky @@ -134,6 +140,18 @@ public class FFMPGenerator extends CompositeProductGenerator implements private static final String productType = "ffmp"; + /** + * The thought was this will eventually be dynamic when We start writing + * long time source records to a DAO. This is the time backward limit for FFTI and cache load data. + */ + public static final int SOURCE_CACHE_TIME = 6; + + /** + * The thought was this will eventually be dynamic, static in AWIPS I. + * This is the time back limit for Flash Flood Guidance sources + */ + public static final int FFG_SOURCE_CACHE_TIME = 24; + /** ArrayList of domains to filter for */ private ArrayList domains = null; @@ -199,7 +217,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements this.pathManager = PathManagerFactory.getPathManager(); - statusHandler.handle(Priority.DEBUG, getGeneratorName() + statusHandler.handle(Priority.INFO, getGeneratorName() + " process Filter Config..."); domains = new ArrayList(); boolean configValid = getRunConfig().isPopulated(); @@ -418,7 +436,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements } } else { statusHandler - .debug(getGeneratorName() + .info(getGeneratorName() + ": templates not loaded yet. Skipping product"); } } @@ -500,7 +518,8 @@ public class FFMPGenerator extends CompositeProductGenerator implements statusHandler.handle(Priority.DEBUG, "Checking status ..." + fftiDone); } catch (InterruptedException e) { - e.printStackTrace(); + statusHandler.handle(Priority.DEBUG, + "Checking status failed!" + e); } } @@ -574,16 +593,19 @@ public class FFMPGenerator extends CompositeProductGenerator implements @Override public void run() { try { - logger.debug("ProcessProduct: Starting thread " - + ffmpProduct.getSourceName()); + statusHandler.handle( + Priority.DEBUG, + "ProcessProduct: Starting thread " + + ffmpProduct.getSourceName()); process(); - logger.debug("ProcessProduct: Finishing thread " - + ffmpProduct.getSourceName()); + statusHandler.handle( + Priority.DEBUG, + "ProcessProduct: Finishing thread " + + ffmpProduct.getSourceName()); } catch (Exception e) { processes.remove(ffmpProduct.getSourceName()); - logger.error("ProcessProduct: removed " - + ffmpProduct.getSourceName()); - e.printStackTrace(); + statusHandler.handle(Priority.ERROR, "ProcessProduct: removed " + + ffmpProduct.getSourceName(), e); } } @@ -713,7 +735,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements generator, ffmpRec, ffmp.getFFTISource()); fftiSources.add(ffmp.getFFTISource()); - // System.out.println("Adding source to FFTISources!!!!!!!!!!!!"+ffmpRec.getSourceName()); ffti.processFFTI(); } } @@ -735,7 +756,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements while (productKeys.size() > 0) { // wait for all threads to finish before returning try { - Thread.sleep(50); + Thread.sleep(100); statusHandler.handle(Priority.DEBUG, "Checking status ..." + productKeys.size()); for (String source : productKeys.keySet()) { @@ -743,7 +764,8 @@ public class FFMPGenerator extends CompositeProductGenerator implements "Still processing ..." + source); } } catch (InterruptedException e) { - e.printStackTrace(); + statusHandler.handle(Priority.WARN, + "Product Procesing Interrupted! " + e); } } } @@ -865,7 +887,8 @@ public class FFMPGenerator extends CompositeProductGenerator implements try { Thread.sleep(100); } catch (InterruptedException e) { - + statusHandler.handle(Priority.WARN, + "Domain processing Interrupted!", e); } } } @@ -974,8 +997,8 @@ public class FFMPGenerator extends CompositeProductGenerator implements getAbsoluteSourceFileName(sourceId)); try { - sbl = (SourceBinList) SerializationUtil - .transformFromThrift(FileUtil.file2bytes(f.getFile(), true)); + sbl = SerializationUtil + .transformFromThrift(SourceBinList.class, FileUtil.file2bytes(f.getFile(), true)); } catch (FileNotFoundException fnfe) { statusHandler.handle(Priority.ERROR, "Unable to locate file " + f.getName()); @@ -983,7 +1006,8 @@ public class FFMPGenerator extends CompositeProductGenerator implements statusHandler.handle(Priority.ERROR, "Unable to read file " + f.getName()); } catch (IOException ioe) { - ioe.printStackTrace(); + statusHandler.handle(Priority.ERROR, "General IO problem with file " + + f.getName(), ioe); } return sbl; @@ -1092,7 +1116,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements statusHandler.handle( Priority.ERROR, "Unable to locate new FFG file. " - + pattern.toString()); + + pattern.toString(), e); } } } @@ -1124,11 +1148,8 @@ public class FFMPGenerator extends CompositeProductGenerator implements siteKey = parts[0]; } - container = loadFFMPDataContainer(siteSourceKey, - - hucs, siteKey, - - config.getCWA(), backDate); + container = loadFFMPDataContainer(siteSourceKey, hucs, siteKey, + config.getCWA(), backDate); if (container != null) { ffmpData.put(siteSourceKey, container); @@ -1200,7 +1221,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements statusHandler.handle(Priority.ERROR, getGeneratorName() + ": filter: " + filter.getName() + ": failed to route filter to generator", e); - e.printStackTrace(); } filter.setValidTime(new Date(System.currentTimeMillis())); @@ -1262,7 +1282,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements boolean write = true; try { - // write out the fast loader buddy file + // write out the fast loader cache file long ptime = System.currentTimeMillis(); SourceXML source = getSourceConfig().getSource( @@ -1274,15 +1294,16 @@ public class FFMPGenerator extends CompositeProductGenerator implements sourceName = source.getDisplayName(); sourceSiteDataKey = sourceName; // FFG is so infrequent go back a day - backDate = new Date(config.getDate().getTime() - - (3600 * 1000 * 24)); + backDate = new Date( + config.getDate().getTime() + - (TimeUtil.MILLIS_PER_HOUR * FFG_SOURCE_CACHE_TIME)); } else { sourceName = ffmpRec.getSourceName(); sourceSiteDataKey = sourceName + "-" + ffmpRec.getSiteKey() + "-" + dataKey; backDate = new Date(ffmpRec.getDataTime().getRefTime() .getTime() - - (3600 * 1000 * 6)); + - (TimeUtil.MILLIS_PER_HOUR * SOURCE_CACHE_TIME)); } // deal with setting of needed HUCS @@ -1336,7 +1357,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements if (newDate != null && oldDate != null) { if ((ffmpRec.getDataTime().getRefTime().getTime() - newDate .getTime()) >= (source - .getExpirationMinutes(ffmpRec.getSiteKey()) * 60 * 1000)) { + .getExpirationMinutes(ffmpRec.getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE)) { // force a re-query back to the newest time in // existing source container, this will fill in // gaps @@ -1348,10 +1369,12 @@ public class FFMPGenerator extends CompositeProductGenerator implements ffmpRec.getWfo(), source, ffmpRec .getSiteKey()); - } else if (oldDate.after(new Date(backDate - .getTime() - - (source.getExpirationMinutes(ffmpRec - .getSiteKey()) * 60 * 1000)))) { + } else if (oldDate + .after(new Date( + backDate.getTime() + - (source + .getExpirationMinutes(ffmpRec + .getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE)))) { // force a re-query back to barrierTime for // existing source container, this happens if // the @@ -1423,14 +1446,14 @@ public class FFMPGenerator extends CompositeProductGenerator implements // this is defensive for if errors get thrown if (backDate == null) { backDate = new Date((System.currentTimeMillis()) - - (3600 * 1000 * 6)); + - (TimeUtil.MILLIS_PER_HOUR * SOURCE_CACHE_TIME)); } fdc.purge(backDate); if (write) { // write it out - writeLoaderBuddyFiles(fdc); + writeCacheFiles(fdc); } } } @@ -1451,37 +1474,31 @@ public class FFMPGenerator extends CompositeProductGenerator implements long time = System.currentTimeMillis(); FFMPDataContainer fdc = null; + FFMPAggregateRecord record = null; + boolean populated = false; - synchronized (hucs) { - for (String huc : hucs) { - - FFMPBasinData basinData = null; - - if (checkBuddyFile(sourceSiteDataKey, huc, wfo, backDate)) { - try { - basinData = readLoaderBuddyFile(sourceSiteDataKey, huc, - wfo, backDate); - } catch (Exception e) { - statusHandler.handle( - Priority.ERROR, - "General Error Reading buddy file: " - + e.getMessage()); - } - - if (fdc == null) { - fdc = new FFMPDataContainer(sourceSiteDataKey, hucs); - } - } - - if (basinData != null) { - fdc.setBasinBuddyData(basinData, huc); - } + if (checkCacheFile(sourceSiteDataKey, wfo, backDate)) { + try { + record = readCacheFile(sourceSiteDataKey, wfo, backDate); + } catch (Exception e) { + statusHandler.handle(Priority.ERROR, + "General Error Reading cache file: " + e.getMessage()); } + + if (fdc == null && record != null) { + // creates a place holder for this source + fdc = new FFMPDataContainer(sourceSiteDataKey, hucs, record); + populated = true; + } + } + + if (record != null && !populated) { + fdc.setCacheData(record); } if (fdc != null) { long time2 = System.currentTimeMillis(); - statusHandler.handle(Priority.DEBUG, "Loaded Source files: in " + statusHandler.handle(Priority.INFO, "Loaded Source files: in " + (time2 - time) + " ms: source: " + sourceSiteDataKey); } @@ -1489,60 +1506,59 @@ public class FFMPGenerator extends CompositeProductGenerator implements } /** - * Load existing buddy file + * Load existing cache file * * @param sourceSiteDataKey - * @param huc * @param wfo * @return * @throws IOException */ - private FFMPBasinData readLoaderBuddyFile(String sourceSiteDataKey, - String huc, String wfo, Date backDate) throws IOException { + private FFMPAggregateRecord readCacheFile(String sourceSiteDataKey, String wfo, + Date backDate) throws IOException { - File file = new File(sharePath + wfo + "/" + sourceSiteDataKey + "-" - + huc + ".bin"); - FFMPBasinData basinData = null; - BufferedInputStream is = null; + File file = new File(sharePath + wfo + "/" + sourceSiteDataKey + ".bin"); + FFMPAggregateRecord record = null; + GZIPInputStream gis = null; try { - is = new BufferedInputStream(new FileInputStream(file)); + gis = new GZIPInputStream(new BufferedInputStream(new FileInputStream(file))); DynamicSerializationManager dsm = DynamicSerializationManager .getManager(SerializationType.Thrift); - basinData = (FFMPBasinData) dsm.deserialize(is); + record = (FFMPAggregateRecord) dsm.deserialize(gis); } catch (SerializationException e) { statusHandler .handle(Priority.ERROR, - "Serialization Error Reading buddy file: " + "Serialization Error Reading cache file: " + e.getMessage()); + } catch (IOException e) { statusHandler.handle(Priority.ERROR, - "IO Error Reading buddy file: " + e.getMessage()); + "IO Error Reading cache file: " + e.getMessage()); } catch (Exception e) { statusHandler.handle(Priority.ERROR, - "General Error Reading buddy file: " + e.getMessage()); + "General Error Reading cache file: " + e.getMessage()); } catch (Throwable t) { statusHandler.handle(Priority.ERROR, - "Bogus Thrift Error Reading buddy file: " + t.getMessage()); + "Bogus Thrift Error Reading cache file: " + t.getMessage()); } finally { - if (is != null) { - is.close(); + if (gis != null) { + gis.close(); } } - return basinData; + return record; } /** - * Write buddy file + * Write cache file * * @param sourceSiteDataKey * @param huc * @param wfo * @return */ - public void writeLoaderBuddyFiles(FFMPDataContainer fdc) { + public void writeCacheFiles(FFMPDataContainer fdc) { // Write all huc levels in separate files File fileDir = new File("" + sharePath + config.getCWA()); @@ -1555,7 +1571,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements } /** - * Inner class to thread writing of BuddyFiles + * Inner class to thread writing of cache files * * @author dhladky * @@ -1569,7 +1585,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements long time = System.currentTimeMillis(); write(); long time2 = System.currentTimeMillis(); - statusHandler.handle(Priority.DEBUG, "Wrote loader files: in " + statusHandler.handle(Priority.INFO, "Wrote cache file: in " + (time2 - time) + " ms :" + fdc.getFilePath()); } catch (Exception e) { statusHandler.handle(Priority.ERROR, @@ -1604,61 +1620,69 @@ public class FFMPGenerator extends CompositeProductGenerator implements if (lockfile.canWrite()) { // write the lock if we can even write to anything - synchronized (fdc.getKeys()) { - for (String huc : fdc.getKeys()) { + FFMPAggregateRecord cacheRecord = null; - FFMPBasinData fbd = fdc.getBasinData(huc); + synchronized (fdc) { - if (fbd.getBasins().size() > 0) { + cacheRecord = new FFMPAggregateRecord(); + // times for Guidance basins will be null + cacheRecord.setTimes(fdc.getOrderedTimes()); - String tmpFilePath = fileName + "-" + huc - + ".tmp"; - BufferedOutputStream os = null; + for (Entry entry : fdc + .getBasinMap().entrySet()) { + FFMPBasinData fbd = entry.getValue(); + fbd.setCache(); + cacheRecord.setBasinData(fbd); + } + } - try { - File file = new File(tmpFilePath); - file.createNewFile(); + if (cacheRecord.getBasinsMap().size() > 0) { - if (file.canWrite()) { - os = new BufferedOutputStream( - new FileOutputStream(file)); - DynamicSerializationManager dsm = DynamicSerializationManager - .getManager(SerializationType.Thrift); - dsm.serialize(fbd, os); - fileNames.put(tmpFilePath, fileName - + "-" + huc + ".bin"); - } else { - statusHandler - .handle(Priority.WARN, - "Can not write buddy file: " - + file.getAbsolutePath()); - } - } catch (SerializationException e) { - statusHandler.handle(Priority.ERROR, - "Serialization Error Writing buddy file: " - + e.getMessage()); - } catch (IOException e) { - statusHandler.handle(Priority.ERROR, - "IO Error Writing buddy file: " - + e.getMessage()); - } catch (Exception e) { - statusHandler.handle(Priority.ERROR, - "General Error Writing buddy file: " - + e.getMessage()); - } finally { - if (os != null) { - os.close(); - } - } + String tmpFilePath = fileName + ".tmp"; + GZIPOutputStream gos = null; + + try { + File file = new File(tmpFilePath); + file.createNewFile(); + + if (file.canWrite()) { + gos = new GZIPOutputStream(new BufferedOutputStream( + new FileOutputStream(file))); + DynamicSerializationManager dsm = DynamicSerializationManager + .getManager(SerializationType.Thrift); + dsm.serialize(cacheRecord, gos); + fileNames.put(tmpFilePath, fileName + + ".bin"); + } else { + statusHandler.handle( + Priority.WARN, + "Can not write cache file: " + + file.getAbsolutePath()); + } + } catch (SerializationException e) { + statusHandler.handle(Priority.ERROR, + "Serialization Error Writing cache file: " + + e.getMessage()); + } catch (IOException e) { + statusHandler.handle( + Priority.ERROR, + "IO Error Writing cache file: " + + e.getMessage()); + } catch (Exception e) { + statusHandler.handle(Priority.ERROR, + "General Error Writing cache file: " + + e.getMessage()); + } finally { + if (gos != null) { + gos.close(); } } } } + } catch (Exception e) { - statusHandler - .handle(Priority.ERROR, - "Error writing Buddy File group: " - + e.getMessage()); + statusHandler.handle(Priority.ERROR, + "Error writing cache File: " + e.getMessage()); } finally { // rename the files to real path try { @@ -1684,31 +1708,29 @@ public class FFMPGenerator extends CompositeProductGenerator implements } catch (Exception e) { statusHandler.handle( Priority.ERROR, - "IO Error Renaming buddy file: " + "IO Error Renaming cache file: " + e.getMessage()); } } } catch (Exception e) { statusHandler.handle(Priority.ERROR, - "IO Error writing buddy files: " + e.getMessage()); + "IO Error writing cache files: " + e.getMessage()); } } } /** - * Load existing buddy file + * Load existing cache file * * @param sourceSiteDataKey - * @param huc * @param wfo * @return */ - public boolean checkBuddyFile(String sourceSiteDataKey, String huc, - String wfo, Date backDate) { + public boolean checkCacheFile(String sourceSiteDataKey, String wfo, + Date backDate) { - File file = new File(sharePath + wfo + "/" + sourceSiteDataKey + "-" - + huc + ".bin"); + File file = new File(sharePath + wfo + "/" + sourceSiteDataKey + ".bin"); String sourceName = sourceSiteDataKey.split("-")[0]; SourceXML source = getSourceConfig().getSourceByDisplayName(sourceName); @@ -1875,8 +1897,8 @@ public class FFMPGenerator extends CompositeProductGenerator implements getAbsoluteFFTIFileName(fftiName)); try { - ffti = (FFTIData) SerializationUtil.transformFromThrift(FileUtil - .file2bytes(f.getFile(), true)); + ffti = SerializationUtil.transformFromThrift(FFTIData.class, + FileUtil.file2bytes(f.getFile(), true)); } catch (FileNotFoundException fnfe) { statusHandler.handle(Priority.ERROR, "Unable to locate file " + f.getName(), fnfe); diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPConfig.java b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPConfig.java index 4be04071ce..68459bae77 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPConfig.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPConfig.java @@ -221,12 +221,12 @@ public class FFMPConfig { } /** - * Get the DHR record + * Get the RADAR record * * @param uri * @return */ - private Object getDHRRecord(String uri) { + private Object getRADARRecord(String uri) { Object record = null; try { record = ScanCommonUtils.getRadarRecord(uri); @@ -398,7 +398,7 @@ public class FFMPConfig { } else if (source.getDataType().equals( FFMPSourceConfigurationManager.DATA_TYPE.RADAR .getDataType())) { - Object dataObject = getDHRRecord(dataUri); + Object dataObject = getRADARRecord(dataUri); if (dataObject != null) { // process as a VGB too diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPInterpolatedGuidanceDelay.java b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPInterpolatedGuidanceDelay.java index be051647fa..c192b23d84 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPInterpolatedGuidanceDelay.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPInterpolatedGuidanceDelay.java @@ -22,6 +22,7 @@ package com.raytheon.uf.edex.plugin.ffmp.common; import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Map.Entry; import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasin; @@ -30,6 +31,7 @@ import com.raytheon.uf.common.dataplugin.ffmp.FFMPDataContainer; import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceBasin; import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord; import com.raytheon.uf.common.monitor.xml.SourceXML; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.edex.plugin.ffmp.FFMPGenerator; /** @@ -41,6 +43,7 @@ import com.raytheon.uf.edex.plugin.ffmp.FFMPGenerator; * ------------ ---------- ----------- -------------------------- * 29 July, 2011 6772 dhladky Initial creation * 29 July, 2012 578 dhladky memory work + * 27 Jan, 2013 1478 dhladky Changed arraylist to list for times, more constants * * * @author dhladky @@ -96,15 +99,16 @@ public class FFMPInterpolatedGuidanceDelay { qpeContainer = generator.getFFMPDataContainer(qpeSource.getSourceName() + "-" + siteKey + "-" + siteKey, hucs, backDate); - long expirationTime = qpeSource.getExpirationMinutes(siteKey) * 60 * 1000; - // determine lag_time + long expirationTime = qpeSource.getExpirationMinutes(siteKey) + * TimeUtil.MILLIS_PER_MINUTE; + // determine lag_time long lagTime = (currentRecord.getDataTime().getRefTime().getTime()) - + (long) (ffgSource.getDurationHour() * 60 * 1000); + + (long) (ffgSource.getDurationHour() * TimeUtil.MILLIS_PER_MINUTE); // Determine hour fraction. int fraction_Hr = (int) (((float) (currentRecord.getDataTime() .getRefTime().getTime() - (lagTime - guidFrequency))) / (float) guidFrequency); // Gets the ordered times for QPE - ArrayList orderedTimes = qpeContainer + List orderedTimes = qpeContainer .getOrderedTimes(currentRecord.getDataTime().getRefTime()); // EQUATION: Guid = GuidOld + R i/d (GuidNew - GuidOld) diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java index 022f857a15..dafc0fbcc0 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java @@ -44,6 +44,7 @@ import com.raytheon.uf.common.monitor.xml.SourceXML; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.edex.plugin.ffmp.FFMPGenerator; /** @@ -54,8 +55,8 @@ import com.raytheon.uf.edex.plugin.ffmp.FFMPGenerator; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 01, 2011 dhladky Initial creation - * July 13, 2012 dhladky Revamped to help memory + * Apr 01, 2011 dhladky Initial creation + * July 13, 2012 dhladky Revamped to help memory * * * @@ -443,7 +444,6 @@ public class FFTI implements Runnable { "Failed to evaluate Ratio/Diff. " + attribute.getAttributeName() + ": " + displayName + "\n" + e); - e.printStackTrace(); } } @@ -826,9 +826,9 @@ public class FFTI implements Runnable { } long cur = config.getDate().getTime(); - long timeBack = (long) (duration * 3600 * 1000); + long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); Date backDate = new Date(cur - timeBack); - long expirationTime = ffmpSource.getExpirationMinutes(fftiSiteKey) * 60 * 1000; + long expirationTime = ffmpSource.getExpirationMinutes(fftiSiteKey) * TimeUtil.MILLIS_PER_MINUTE; FFMPDataContainer fdc = null; @@ -894,6 +894,15 @@ public class FFTI implements Runnable { return accumulator; } + /** + * Gets the ratio and difference values for this site + * @param qSourceKey + * @param qSiteKey + * @param ffgType + * @param duration + * @param unit + * @return + */ private FFTIRatioDiff getRatioAndDiffForSite(String qSourceKey, String qSiteKey, String ffgType, double duration, String unit) { @@ -923,13 +932,13 @@ public class FFTI implements Runnable { values.setUnit(unit); long cur = config.getDate().getTime(); - long timeBack = (long) (duration * 3600 * 1000); + long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); Date backDate = new Date(cur - timeBack); - long expirationTime = ffmpQSource.getExpirationMinutes(qSiteKey) * 60 * 1000; + long expirationTime = ffmpQSource.getExpirationMinutes(qSiteKey) * TimeUtil.MILLIS_PER_MINUTE; // make sure we have data Date ffgBackDate = new Date(config.getDate().getTime() - - (3600 * 1000 * 24)); + - (TimeUtil.MILLIS_PER_HOUR * FFMPGenerator.FFG_SOURCE_CACHE_TIME)); String primarySource = ffmpgen.fscm.getPrimarySource(ffmpQSource); ProductXML product = ffmpgen.fscm.getProduct(primarySource); @@ -950,7 +959,7 @@ public class FFTI implements Runnable { if (guidSourceExpiration == 0l) { guidSourceExpiration = iguidSource - .getExpirationMinutes(qSiteKey) * 60 * 1000; + .getExpirationMinutes(qSiteKey) * TimeUtil.MILLIS_PER_MINUTE; break; } } @@ -1046,7 +1055,7 @@ public class FFTI implements Runnable { SourceXML ffmpQSource, double duration, String qSiteKey) { long cur = config.getDate().getTime(); - long timeBack = (long) (duration * 3600 * 1000); + long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); Date backDate = new Date(cur - timeBack); long expirationTime = ffmpQSource.getExpirationMinutes(qSiteKey); Double gapVal = 0.0; @@ -1054,14 +1063,14 @@ public class FFTI implements Runnable { if (qpeContainer.getOrderedTimes(backDate) != null) { gapVal = 0.0; - ArrayList gaps = FFMPGap.getGaps( + List gaps = FFMPGap.getGaps( qpeContainer.getOrderedTimes(backDate), expirationTime, backDate, config.getDate()); for (FFMPGap gap : gaps) { gapVal += gap.getGap(); } - gapVal = gapVal / 60; + gapVal = gapVal / TimeUtil.MINUTES_PER_HOUR; } return gapVal; diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/META-INF/MANIFEST.MF index 32525a99e7..4b8090eb4f 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/META-INF/MANIFEST.MF @@ -11,7 +11,8 @@ Require-Bundle: com.raytheon.uf.edex.auth;bundle-version="1.12.2", com.raytheon.uf.common.status;bundle-version="1.12.1174", com.raytheon.uf.common.localization, com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174", - com.raytheon.uf.common.useradmin;bundle-version="1.0.0" + com.raytheon.uf.common.useradmin;bundle-version="1.0.0", + com.raytheon.uf.common.time;bundle-version="1.12.1174" Import-Package: com.raytheon.uf.common.localization, com.raytheon.uf.common.serialization, com.raytheon.uf.common.status, diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/src/com/raytheon/uf/edex/plugin/nwsauth/FileManager.java b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/src/com/raytheon/uf/edex/plugin/nwsauth/FileManager.java index c308db748d..13d71d3320 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/src/com/raytheon/uf/edex/plugin/nwsauth/FileManager.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/src/com/raytheon/uf/edex/plugin/nwsauth/FileManager.java @@ -19,9 +19,11 @@ **/ package com.raytheon.uf.edex.plugin.nwsauth; -import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; import javax.xml.bind.JAXBException; @@ -40,6 +42,7 @@ import com.raytheon.uf.common.serialization.JAXBManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.util.TimeUtil; /** * Uses localization data to determine role/permissions. Intentionally @@ -51,7 +54,9 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 09, 2013 1412 djohnson Moved file writing from viz plugin to server-side. + * Jan 09, 2013 1412 djohnson Moved file writing from viz plugin to server-side. + * Jan 17, 2013 1412 djohnson Check files for having been modified each time data is requested, + * in case they were written by another member of the cluster. * * * @@ -69,14 +74,22 @@ class FileManager { private final String ROLE_DIR = "roles"; - private final Map roleDataMap = new HashMap(); + private final AtomicLong lastReadTime = new AtomicLong(-1L); + + /** + * Application name -> Role Data. + */ + private final ConcurrentMap roleDataMap = new ConcurrentHashMap(); /** * Application name -> LocalizationFile map. */ - private final Map roleFileMap = new HashMap(); + private final ConcurrentMap roleFileMap = new ConcurrentHashMap(); - private FileManager() { + /** + * Package-level visibility so tests can create new instances. + */ + FileManager() { readXML(); } @@ -117,31 +130,54 @@ class FileManager { private void readXML() { try { - getJaxbManager(); - - IPathManager pm = PathManagerFactory.getPathManager(); - LocalizationContext[] contexts = new LocalizationContext[2]; - contexts[0] = pm.getContext(LocalizationType.COMMON_STATIC, - LocalizationLevel.BASE); - contexts[1] = pm.getContext(LocalizationType.COMMON_STATIC, - LocalizationLevel.SITE); - LocalizationFile[] roleFiles = pm.listFiles(contexts, ROLE_DIR, - new String[] { ".xml" }, false, true); - + LocalizationFile[] roleFiles = getUserRoleLocalizationFiles(); + boolean needToReadFiles = false; for (LocalizationFile lf : roleFiles) { - NwsRoleData roleData = lf.jaxbUnmarshal(NwsRoleData.class, - getJaxbManager()); + final long fileLastModified = lf.getFile().lastModified(); + final long lastTimeFilesWereRead = lastReadTime.get(); - if (roleData != null) { - this.roleDataMap.put(roleData.getApplication(), roleData); - this.roleFileMap.put(roleData.getApplication(), lf); + if (fileLastModified > lastTimeFilesWereRead) { + needToReadFiles = true; + break; } } + + if (needToReadFiles) { + for (LocalizationFile lf : roleFiles) { + final long fileLastModified = lf.getFile().lastModified(); + final long lastTimeFilesWereRead = lastReadTime.get(); + + if (fileLastModified < lastTimeFilesWereRead) { + continue; + } + NwsRoleData roleData = lf.jaxbUnmarshal(NwsRoleData.class, + getJaxbManager()); + + if (roleData != null) { + final String application = roleData.getApplication(); + this.roleDataMap.put(application, roleData); + this.roleFileMap.put(application, lf); + } + } + } + lastReadTime.set(TimeUtil.currentTimeMillis()); } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); } } + private LocalizationFile[] getUserRoleLocalizationFiles() { + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext[] contexts = new LocalizationContext[2]; + contexts[0] = pm.getContext(LocalizationType.COMMON_STATIC, + LocalizationLevel.BASE); + contexts[1] = pm.getContext(LocalizationType.COMMON_STATIC, + LocalizationLevel.SITE); + LocalizationFile[] roleFiles = pm.listFiles(contexts, ROLE_DIR, + new String[] { ".xml" }, false, true); + return roleFiles; + } + private JAXBManager getJaxbManager() throws JAXBException { if (jaxbManager == null) { jaxbManager = new JAXBManager(NwsRoleData.class, @@ -154,13 +190,15 @@ class FileManager { * @return */ public Map getRoleDataMap() { + readXML(); return roleDataMap; } /** * @param roleDataWithChanges */ - public void writeApplicationRoleData(Map roleDataWithChanges) { + public void writeApplicationRoleData( + Map roleDataWithChanges) { for (Entry entry : roleDataWithChanges.entrySet()) { final String application = entry.getKey(); roleDataMap.put(application, entry.getValue()); diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml index 67ab28709d..61c231cbea 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml @@ -89,6 +89,8 @@ + + com.raytheon.localization.site/common_static/purge com.raytheon.localization.site/cave_static/colormaps @@ -119,6 +121,7 @@ com.raytheon.localization.site/common_static/radar/rmr/rmrAvailableRequests.xml com.raytheon.localization.site/common_static/shef com.raytheon.localization.site/common_static/roles + com.raytheon.localization.site/common_static/datadelivery diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/scripts/RegistryIndices.sql b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/scripts/RegistryIndices.sql new file mode 100644 index 0000000000..cb1fa73597 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/scripts/RegistryIndices.sql @@ -0,0 +1,4 @@ +CREATE INDEX "intlstring_localizedStrings_idx" ON intlstring_localizedstrings USING btree (intlstring_key); +CREATE INDEX "versionInfo_idx" ON versioninfo USING btree (versionname,userversionname); +CREATE INDEX registryobject_slot_idx ON registryobject_slot USING btree (registryobject_id); +CREATE INDEX value_value_idx ON value_value USING btree (value_key); \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/DbInit.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/DbInit.java index 3385e3a615..609b624349 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/DbInit.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/DbInit.java @@ -20,7 +20,11 @@ package com.raytheon.uf.edex.registry.ebxml.dao; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.ResultSet; @@ -28,7 +32,10 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; +import java.util.Enumeration; import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException; import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest; @@ -48,6 +55,7 @@ import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.util.ReflectionUtil; +import com.raytheon.uf.edex.core.props.PropertiesFactory; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; import com.raytheon.uf.edex.registry.ebxml.services.lifecycle.LifecycleManagerImpl; import com.raytheon.uf.edex.registry.ebxml.services.util.RegistrySessionManager; @@ -169,6 +177,15 @@ public class DbInit extends RegistryDao { e); } + statusHandler.info("Executing additional registry SQL..."); + try { + executeRegistrySql(); + } catch (EbxmlRegistryException e) { + throw new EbxmlRegistryException( + "An unexpected database error occurred while executing additional sql on the registry", + e); + } + try { populateDB(); } catch (SerializationException e) { @@ -398,6 +415,84 @@ public class DbInit extends RegistryDao { } + /** + * Executes any additional SQL statements contained in the res/scripts + * directory of this jar. The purpose of this method is primarily to add + * additional indices that cannot be automaically be generated by Hibernate + * + * @throws EbxmlRegistryException + */ + private void executeRegistrySql() throws EbxmlRegistryException { + JarFile jar = null; + + try { + jar = new JarFile(PropertiesFactory.getInstance() + .getEnvProperties().getEnvValue("PLUGINDIR") + + "com.raytheon.uf.edex.registry.ebxml.jar"); + } catch (IOException e) { + throw new EbxmlRegistryException("Unable to find registry jar!", e); + } + + Enumeration entries = jar.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String name = entry.getName(); + if (name.startsWith("res/scripts") && name.endsWith(".sql")) { + BufferedReader reader = null; + InputStream stream = null; + + try { + stream = jar.getInputStream(entry); + reader = new BufferedReader(new InputStreamReader(stream)); + String line = null; + final StringBuilder buffer = new StringBuilder(); + while ((line = reader.readLine()) != null) { + buffer.append(line); + } + this.doInTransaction(new RegistryTransactionCallback() { + @Override + public Object execute(Session session) + throws EbxmlRegistryException { + session.doWork(new Work() { + @Override + public void execute(Connection connection) + throws SQLException { + Statement stmt = connection + .createStatement(); + stmt.execute(buffer.toString()); + connection.commit(); + } + }); + return null; + } + }); + } catch (Exception e) { + throw new EbxmlRegistryException( + "Unable to execute SQL Scripts for registry", e); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + throw new EbxmlRegistryException( + "Unable to close file reader while reading registry SQL files", + e); + } + } + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + throw new EbxmlRegistryException( + "Unable to close file input stream while reading registry SQL files", + e); + } + } + } + } + } + } + /** * Method used to ensure that all objects added during the registry * initialization have an owner assigned to them. If no owner is assigned, diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/utility/edex_static/base/stats/registryProcessStats.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/utility/edex_static/base/stats/registryProcessStats.xml new file mode 100644 index 0000000000..7c3ed01ee8 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/utility/edex_static/base/stats/registryProcessStats.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/AggregateManager.java b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/AggregateManager.java index 44c27f32d7..40af314884 100644 --- a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/AggregateManager.java +++ b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/AggregateManager.java @@ -19,7 +19,9 @@ **/ package com.raytheon.uf.edex.stats; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; @@ -28,11 +30,17 @@ import java.util.List; import java.util.Map; import java.util.TimeZone; +import javax.xml.bind.JAXBException; + +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.raytheon.uf.common.event.Event; +import com.raytheon.uf.common.serialization.JAXBManager; import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.stats.AggregateRecord; +import com.raytheon.uf.common.stats.StatsGrouping; +import com.raytheon.uf.common.stats.StatsGroupingColumn; import com.raytheon.uf.common.stats.StatsRecord; import com.raytheon.uf.common.stats.xml.StatisticsAggregate; import com.raytheon.uf.common.stats.xml.StatisticsEvent; @@ -61,6 +69,7 @@ import com.raytheon.uf.edex.stats.util.ConfigLoader; * Nov 07, 2012 1317 mpduff Updated Configuration Files. * Nov 28, 2012 1350 rjpeter Simplied aggregation and added aggregation with current db aggregate records. * Jan 07, 2013 1451 djohnson Use newGmtCalendar(). + * Jan 15, 2013 1487 djohnson Use xml for the grouping information on an {@link AggregateRecord}. * * * @author jsanchez @@ -70,6 +79,17 @@ public class AggregateManager { private static final IUFStatusHandler statusHandler = UFStatus .getHandler(AggregateManager.class); + private static final Object[] EMPTY_OBJ_ARR = new Object[0]; + + private static final JAXBManager JAXB_MANAGER; + static { + try { + JAXB_MANAGER = new JAXBManager(StatsGroupingColumn.class); + } catch (JAXBException e) { + throw new ExceptionInInitializerError(e); + } + } + /** In minutes */ private int bucketInterval; @@ -255,8 +275,6 @@ public class AggregateManager { Map> rval = new HashMap>(); TimeRange timeRange = null; Multimap eventsByGroup = null; - final Object[] EMPTY_OBJ_ARR = new Object[0]; - StringBuilder group = new StringBuilder(); for (StatsRecord record : records) { if ((timeRange == null) @@ -275,30 +293,11 @@ public class AggregateManager { Event event = SerializationUtil.transformFromThrift( Event.class, record.getEvent()); - // determine group - boolean addDelim = false; - Iterator gMethodIter = statEvent.getGroupByMethods() - .iterator(); - Iterator gFieldNameIter = statEvent - .getGroupList().iterator(); - group.setLength(0); - - while (gMethodIter.hasNext() && gFieldNameIter.hasNext()) { - Method m = gMethodIter.next(); - String field = gFieldNameIter.next().getName(); - String gVal = String - .valueOf(m.invoke(event, EMPTY_OBJ_ARR)); - - if (addDelim) { - group.append('-'); - } else { - addDelim = true; - } - - group.append(field).append(':').append(gVal); + String groupAsString = determineGroupRepresentationForEvent( + statEvent, event); + if (groupAsString != null) { + eventsByGroup.put(groupAsString, event); } - - eventsByGroup.put(group.toString(), event); } catch (Exception e) { statusHandler .error("Error processing event. Aggregation may be inaccurate. ", @@ -309,6 +308,30 @@ public class AggregateManager { return rval; } + @VisibleForTesting + static String determineGroupRepresentationForEvent( + StatisticsEvent statEvent, Event event) + throws IllegalAccessException, InvocationTargetException, + JAXBException { + Iterator gMethodIter = statEvent.getGroupByMethods().iterator(); + Iterator gFieldNameIter = statEvent.getGroupList() + .iterator(); + List groupings = new ArrayList(); + + while (gMethodIter.hasNext() && gFieldNameIter.hasNext()) { + Method m = gMethodIter.next(); + String field = gFieldNameIter.next().getName(); + String gVal = String.valueOf(m.invoke(event, EMPTY_OBJ_ARR)); + + groupings.add(new StatsGrouping(field, gVal)); + } + + StatsGroupingColumn column = new StatsGroupingColumn(); + column.setGroup(groupings); + + return JAXB_MANAGER.marshalToXml(column); + } + /** * Tests if the bucket interval is a valid value. If value is invalid then * value will be set to default value. diff --git a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/data/StatsDataAccumulator.java b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/data/StatsDataAccumulator.java index c21c31ff5e..d207d2d13d 100644 --- a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/data/StatsDataAccumulator.java +++ b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/data/StatsDataAccumulator.java @@ -20,58 +20,72 @@ package com.raytheon.uf.edex.stats.data; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; -import java.util.TreeSet; -import java.util.regex.Pattern; + +import javax.xml.bind.JAXBException; import com.google.common.annotations.VisibleForTesting; -import com.raytheon.uf.common.serialization.SerializationException; -import com.raytheon.uf.common.serialization.SerializationUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.raytheon.uf.common.serialization.JAXBManager; import com.raytheon.uf.common.stats.AggregateRecord; +import com.raytheon.uf.common.stats.StatsGrouping; +import com.raytheon.uf.common.stats.StatsGroupingColumn; import com.raytheon.uf.common.stats.data.GraphData; import com.raytheon.uf.common.stats.data.StatsBin; import com.raytheon.uf.common.stats.data.StatsData; import com.raytheon.uf.common.stats.data.StatsLabelData; -import com.raytheon.uf.common.stats.util.UnitUtils; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.util.CollectionUtil; /** * Accumulates the statistics data. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Nov 15, 2012    728     mpduff      Initial creation
- *
+ * Jan 15, 2013 1487       djohnson    Use xml for the grouping information on an {@link AggregateRecord}.
+ * Jan 17, 2013   1357     mpduff      Remove unit conversions, add time step, other cleanup.
+ * 
  * 
- * + * * @author mpduff * @version 1.0 */ public class StatsDataAccumulator { - private static final Pattern COLON_PATTERN = Pattern.compile(":"); - - private static final Pattern DASH_PATTERN = Pattern.compile("-"); - - private static final String COLON = ":"; private static final IUFStatusHandler statusHandler = UFStatus .getHandler(StatsDataAccumulator.class); + /** + * Constant. + */ + private static final String COLON = ":"; + + /** JaxB manager instance. */ + private static final JAXBManager JAXB_MANAGER; + static { + try { + JAXB_MANAGER = new JAXBManager(StatsGroupingColumn.class); + } catch (JAXBException e) { + throw new ExceptionInInitializerError(e); + } + } + /** List of records */ private AggregateRecord[] records; @@ -108,7 +122,7 @@ public class StatsDataAccumulator { /** * Set the AggregateRecord[] - * + * * @param records * array of AggregateRecord objects */ @@ -122,28 +136,27 @@ public class StatsDataAccumulator { @VisibleForTesting public void setupGroupings() { for (AggregateRecord aggRec : records) { - String grouping = aggRec.getGrouping(); - String[] groupString = DASH_PATTERN.split(grouping); - String group; - String member; - for (String grp : groupString) { - String[] parts = COLON_PATTERN.split(grp); - group = parts[0]; - member = parts[1]; - if (!groupMemberMap.containsKey(group)) { - groupMemberMap.put(group, new TreeSet()); - } + StatsGroupingColumn columnValue = unmarshalGroupingColumnFromRecord(aggRec); - groupMemberMap.get(group).add(member); + final List groups = columnValue.getGroup(); + if (CollectionUtil.isNullOrEmpty(groups)) { + continue; + } + for (StatsGrouping group : groups) { + final String groupName = group.getName(); + if (!groupMemberMap.containsKey(groupName)) { + groupMemberMap.put(groupName, Sets. newTreeSet()); + } + groupMemberMap.get(groupName).add(group.getValue()); } } - groups = new ArrayList(groupMemberMap.keySet()); + groups = Lists.newArrayList(groupMemberMap.keySet()); } /** * Get the GraphData object - * + * * @param groups * List of groups * @return The GraphData object @@ -154,8 +167,6 @@ public class StatsDataAccumulator { // Loop backwards over the data StatsLabelData prevLabelData = null; StatsLabelData statsLabelData = null; - UnitUtils unitUtils = new UnitUtils(eventType, dataType); - unitUtils.setDisplayUnit(displayUnit); for (int i = groups.size() - 1; i >= 0; i--) { String group = groups.get(i); @@ -167,7 +178,7 @@ public class StatsDataAccumulator { prevLabelData = statsLabelData; } - gather(unitUtils, groups); + gather(groups); // StatsLabelData is created and holds all the keys GraphData graphData = new GraphData(); @@ -176,22 +187,24 @@ public class StatsDataAccumulator { graphData.setStatsDataMap(statsDataMap); graphData.setTimeRange(timeRange); graphData.setKeys(new ArrayList(this.statsDataMap.keySet())); - graphData.setUnitUtils(unitUtils); graphData.setKeySequence(groups); + graphData.setTimeStep(this.timeStep); + graphData.setEventType(eventType); + graphData.setDataType(dataType); return graphData; } /** * Create the StatsDataMap keys - * + * * @param unitUtils * UnitUtils object * @param groups * List of groups */ @VisibleForTesting - void createStatsDataMap(UnitUtils unitUtils, List groups) { + void createStatsDataMap(List groups) { Map keySequenceMap = new LinkedHashMap(); for (String key : groups) { keySequenceMap.put(key, ""); @@ -202,21 +215,25 @@ public class StatsDataAccumulator { if (record.getEventType().equals(eventType) && record.getField().equals(dataType)) { + StatsGroupingColumn columnValue = unmarshalGroupingColumnFromRecord(record); + + final List columnValueGroups = columnValue + .getGroup(); + if (CollectionUtil.isNullOrEmpty(columnValueGroups)) { + continue; + } + // Have a matching record for (String key : keySequenceMap.keySet()) { keySequenceMap.put(key, ""); } - String[] groupings = DASH_PATTERN.split(record.getGrouping()); - for (String grouping : groupings) { - String[] parts = COLON_PATTERN.split(grouping); - String group = parts[0]; - String groupMember = parts[1]; + for (StatsGrouping group : columnValueGroups) { for (String key : keySequenceMap.keySet()) { - if (group.equals(key)) { + if (group.getName().equals(key)) { keySequenceMap.put(key, keySequenceMap.get(key) - .concat(groupMember + COLON)); + .concat(group.getValue() + COLON)); break; } } @@ -233,7 +250,7 @@ public class StatsDataAccumulator { if (!statsDataMap.containsKey(builtKey)) { statsDataMap.put(builtKey, new StatsData(builtKey, - timeStep, this.timeRange, unitUtils)); + timeStep, this.timeRange)); } statsDataMap.get(builtKey).addRecord(record); @@ -242,29 +259,48 @@ public class StatsDataAccumulator { } } + /** + * Unmarshals the {@link StatsGroupingColumn} from the + * {@link AggregateRecord}. + * + * @param record + * the aggregate record + * @return the unmarshalled column, or an empty column if unable to + * unmarshal + */ + private static StatsGroupingColumn unmarshalGroupingColumnFromRecord( + AggregateRecord record) { + String groupingXmlAsString = record.getGrouping(); + try { + return (StatsGroupingColumn) JAXB_MANAGER + .unmarshalFromXml(groupingXmlAsString); + } catch (JAXBException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to unmarshal stats grouping column, returning empty record, xml:\n" + + groupingXmlAsString, e); + return new StatsGroupingColumn(); + } + } + /** * Gather the data together in each bin. - * + * * @param unitUtils * UnitUtils object * @param groups * List of groups */ - @SuppressWarnings("unchecked") - private void gather(UnitUtils unitUtils, List groups) { - createStatsDataMap(unitUtils, groups); + private void gather(List groups) { + createStatsDataMap(groups); calculateBins(); + Map newMap = new TreeMap(); for (String key : statsDataMap.keySet()) { - Map newMap = Collections.emptyMap(); - try { - newMap = SerializationUtil.transformFromThrift(Map.class, - SerializationUtil.transformToThrift(bins)); - } catch (SerializationException e) { - statusHandler - .handle(Priority.PROBLEM, - "Error serializing/deserializing StatsBin data. Skipping...", - e); + // Copy the bins object + for (long lkey : bins.keySet()) { + StatsBin sb = new StatsBin(bins.get(lkey)); + newMap.put(lkey, sb); } + StatsData data = statsDataMap.get(key); data.setBins(newMap); data.accumulate(); @@ -323,7 +359,7 @@ public class StatsDataAccumulator { /** * Set the display units. - * + * * @param displayUnit * the displayUnit to set */ @@ -333,7 +369,7 @@ public class StatsDataAccumulator { /** * TimeStep in minutes - * + * * @param timeStep */ public void setTimeStep(int timeStep) { diff --git a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/Archiver.java b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/Archiver.java index 9150f940a2..59dd45cd2e 100644 --- a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/Archiver.java +++ b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/Archiver.java @@ -54,6 +54,7 @@ import com.raytheon.uf.common.time.TimeRange; * ------------ ---------- ----------- -------------------------- * Aug 21, 2012 jsanchez Initial creation. * Nov 09, 2012 dhladky Changed to CSV output + * Jan 24, 2013 1357 mpduff Fix comma output and paths. * * * @@ -91,6 +92,8 @@ public class Archiver { private static final String COMMA = ","; + private static final Pattern NLPattern = Pattern.compile("[\\n\\r]+"); + private static final IUFStatusHandler statusHandler = UFStatus .getHandler(Archiver.class); @@ -116,15 +119,13 @@ public class Archiver { * @param items * @return */ - private String createFilename(TimeRange tr, String eventType, String group) { + private String createFilename(TimeRange tr, String eventType) { SimpleDateFormat fileDateFormatter = new SimpleDateFormat( FILE_DATE_FORMAT); StringBuilder sb = new StringBuilder("stats/aggregates"); String[] chunks = PERIOD_PATTERN.split(eventType); sb.append("/"); - sb.append(group); - sb.append("/"); sb.append(chunks[chunks.length - 1]); sb.append("."); sb.append(fileDateFormatter.format(tr.getStart())); @@ -156,24 +157,29 @@ public class Archiver { double count = agrec.getCount(); if (eventType != null) { - sb.append(eventType).append(COMMA); + sb.append(eventType); } + sb.append(COMMA); if (startDate != null) { - sb.append(dateFormat.format(startDate.getTime())) - .append(COMMA); + sb.append(dateFormat.format(startDate.getTime())); } + sb.append(COMMA); if (endDate != null) { - sb.append(dateFormat.format(endDate.getTime())).append( - COMMA); + sb.append(dateFormat.format(endDate.getTime())); } + sb.append(COMMA); + if (grouping != null) { - sb.append(grouping).append(COMMA); + sb.append(NLPattern.matcher(grouping).replaceAll("")); } + sb.append(COMMA); + if (field != null) { - sb.append(field).append(COMMA); + sb.append(field); } + sb.append(COMMA); sb.append(max).append(COMMA); sb.append(min).append(COMMA); @@ -212,10 +218,9 @@ public class Archiver { for (StatisticsKey key : statisticsMap.keySet()) { String eventType = key.eventType; - String grouping = key.grouping; List records = statisticsMap.get(key); - String filename = createFilename(key.timeRange, eventType, grouping); + String filename = createFilename(key.timeRange, eventType); try { writeToFile(filename, records); } catch (JAXBException e) { @@ -243,8 +248,7 @@ public class Archiver { siteLocalization.getFile().getParentFile().mkdirs(); // Write this to output CSV try { - bw = new BufferedWriter(new FileWriter( - outputFilePath)); + bw = new BufferedWriter(new FileWriter(outputFilePath)); if (bw != null) { for (AggregateRecord agrec : records) { bw.write(getCSVOutput(agrec, dateFormatter)); diff --git a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/ConfigLoader.java b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/ConfigLoader.java index e4e6e01d29..239ebfc79d 100644 --- a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/ConfigLoader.java +++ b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/util/ConfigLoader.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.google.common.annotations.VisibleForTesting; import com.raytheon.uf.common.event.Event; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; @@ -57,6 +58,7 @@ import com.raytheon.uf.common.util.ReflectionUtil; * Aug 21, 2012 jsanchez Updated error handling and validated config files. * Nov 07, 2012 1317 mpduff Update config files. * Nov 29, 2012 1350 rjpeter Updated to static, fixed localization, increased validation. + * Jan 15, 2013 1487 djohnson Make validate() static and public, so it can be run independently. * * * @author jsanchez @@ -158,7 +160,8 @@ public class ConfigLoader { * * @param config */ - private void validate(Map eventMap, + @VisibleForTesting + public static void validate(Map eventMap, StatisticsConfig config) { for (Iterator iter = config.getEvents().iterator(); iter .hasNext();) { diff --git a/edexOsgi/com.raytheon.uf.edex.stats/utility/edex_static/base/stats/edexProcessStats.xml b/edexOsgi/com.raytheon.uf.edex.stats/utility/edex_static/base/stats/edexProcessStats.xml index ed85b9c2e7..90c2d74058 100644 --- a/edexOsgi/com.raytheon.uf.edex.stats/utility/edex_static/base/stats/edexProcessStats.xml +++ b/edexOsgi/com.raytheon.uf.edex.stats/utility/edex_static/base/stats/edexProcessStats.xml @@ -3,6 +3,8 @@ + $TEMPNAME mv $TEMPNAME $LOGFILE -fi +fi # echo "------------------------------ " >> $LOGFILE @@ -42,18 +42,10 @@ echo "------------------------------ " >> $LOGFILE Dte=`date -u ` echo Starting alarm_whfs at $Dte >> $LOGFILE -Dte=`date -u` -echo Invoking roc_checker at $Dte >> $LOGFILE - $WHFS_LOCAL_BIN_DIR/run_roc_checker -# TODO re-enabled report_alarm if needed +$WHFS_LOCAL_BIN_DIR/run_report_alarm -#Dte=`date -u` -#echo Invoking report_alarm at $Dte >> $LOGFILE - -#$WHFS_LOCAL_BIN_DIR/run_report_alarm - -#Dte=`date -u ` -#echo Completed alarm_whfs at $Dte >> $LOGFILE +Dte=`date -u ` +echo Completed alarm_whfs at $Dte >> $LOGFILE diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.py index 68d276abfa..2ac291d476 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/db/objects/ParmID.py @@ -48,50 +48,30 @@ class ParmID(object): else: self.parmLevel = level - self.compositeName = self.parmName + "_" + self.parmLevel self.__encodeIdentifier() elif parmIdentifier is not None: self.__decodeIdentifier(parmIdentifier) - self.compositeName = self.parmName + "_" + self.parmLevel self.__encodeIdentifier() def getParmName(self): return self.parmName - def setParmName(self, parmName): - self.parmName = parmName - def getParmLevel(self): return self.parmLevel - def setParmLevel(self, parmLevel): - self.parmLevel = parmLevel - def getDbId(self): return self.dbId - def setDbId(self, dbId): - self.dbId = dbId - def getCompositeName(self): return self.compositeName - def setCompositeName(self, compositeName): - self.compositeName = compositeName - def getShortParmId(self): return self.shortParmId - def setShortParmId(self, shortParmId): - self.shortParmId = shortParmId - def getParmId(self): return self.parmId - def setParmId(self, parmId): - self.parmId = parmId - def __decodeIdentifier(self, parmIdentifier): parts = parmIdentifier.split(":") nameLevel = parts[0].split("_") @@ -104,9 +84,9 @@ class ParmID(object): self.parmLevel = self.defaultLevel() def __encodeIdentifier(self): + self.compositeName = self.parmName + "_" + self.parmLevel self.shortParmId = self.compositeName + ":" + self.dbId.getShortModelId() - if self.parmId is None or len(self.parmId) == 0: - self.parmId = self.compositeName + ":" + self.dbId.getModelId() + self.parmId = self.compositeName + ":" + self.dbId.getModelId() def isValid(self): if len(self.parmName) is None or len(self.parmLevel) is None or self.dbId is None: diff --git a/tests/.classpath b/tests/.classpath index 65be975a6f..a139e358aa 100644 --- a/tests/.classpath +++ b/tests/.classpath @@ -67,5 +67,9 @@ + + + + diff --git a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/AbstractBandwidthManagerIntTest.java b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/AbstractBandwidthManagerIntTest.java index 48b88f5ca7..32b1c29f6a 100644 --- a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/AbstractBandwidthManagerIntTest.java +++ b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/AbstractBandwidthManagerIntTest.java @@ -151,7 +151,15 @@ public abstract class AbstractBandwidthManagerIntTest { */ protected Subscription createSubscriptionThatFillsUpABucket() { return createSubscriptionWithDataSetSizeInBytes(fullBucketSize); + } + /** + * Create a subscription the fills up ten buckets. + * + * @return the subscription + */ + protected Subscription createSubscriptionThatFillsUpTenBuckets() { + return createSubscriptionWithDataSetSizeInBytes(fullBucketSize * 10); } /** diff --git a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java index e1d4e17338..2e43aef07b 100644 --- a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java +++ b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java @@ -19,8 +19,11 @@ **/ package com.raytheon.uf.edex.datadelivery.bandwidth; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.text.ParseException; @@ -47,6 +50,7 @@ import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSetMetaDat import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSetMetaDataFixture; import com.raytheon.uf.common.datadelivery.registry.ParameterFixture; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture; import com.raytheon.uf.common.datadelivery.registry.Time; import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; @@ -81,6 +85,9 @@ import com.raytheon.uf.edex.datadelivery.retrieval.RetrievalManagerNotifyEvent; * Oct 12, 2012 0726 djohnson Initial creation * Oct 23, 2012 1286 djohnson Create reusable abstract int test. * Dec 11, 2012 1286 djohnson Add test verifying fulfilled retrievals won't cause NPEs when the subscription is updated. + * Jan 25, 2013 1528 djohnson Compare priorities as primitive ints. + * Jan 28, 2013 1530 djohnson Test that all allocations are unscheduled for subscription that doesn't fully schedule. + * Jan 30, 2013 1501 djohnson Fix broken calculations for determining required latency. * * * @@ -313,7 +320,7 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { Subscription subscription2 = createSubscriptionThatFillsUpABucket(); // subscription2 will have higher priority - subscription2.setPriority(subscription.getPriority() + 1); + subscription2.setPriority(SubscriptionPriority.HIGH); // they conflict for cycle hour 8 subscription.getTime().setCycleTimes( @@ -335,16 +342,45 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { BandwidthAllocation unscheduledAllocation = iter.next(); assertEquals( "The first subscription with lower priority should have been the one unscheduled.", - subscription.getPriority().intValue(), + subscription.getPriority().getPriorityValue(), unscheduledAllocation.getPriority(), 0.0); unscheduledAllocation = iter.next(); assertEquals( "The first subscription with lower priority should have been the one unscheduled.", - subscription.getPriority().intValue(), + subscription.getPriority().getPriorityValue(), unscheduledAllocation.getPriority(), 0.0); } + @Test + public void unscheduledSubscriptionUnschedulesAllAllocations() { + String unscheduledSubDataSetName = "willBeUnscheduled"; + Subscription subscription = createSubscriptionThatFillsUpABucket(); + subscription.setDataSetName(unscheduledSubDataSetName); + Subscription subscription2 = createSubscriptionThatFillsUpABucket(); + + // subscription2 will have higher priority + subscription2.setPriority(SubscriptionPriority.HIGH); + + // they conflict for cycle hour 8 + subscription.getTime().setCycleTimes( + Arrays.asList(Integer.valueOf(6), Integer.valueOf(8))); + subscription2.getTime().setCycleTimes( + Arrays.asList(Integer.valueOf(3), Integer.valueOf(8))); + + bandwidthManager.schedule(subscription); + bandwidthManager.schedule(subscription2); + + final List subscriptionRetrievals = bandwidthDao + .getSubscriptionRetrievals(subscription.getProvider(), + unscheduledSubDataSetName); + + for (SubscriptionRetrieval subscriptionRetrieval : subscriptionRetrievals) { + assertThat(subscriptionRetrieval.getStatus(), + is(equalTo(RetrievalStatus.UNSCHEDULED))); + } + } + @Test public void testScheduleSubscriptionWithHigherPrioritySetsOtherAllocationsToUnscheduled() { @@ -352,7 +388,7 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { Subscription subscription2 = createSubscriptionThatFillsUpABucket(); // subscription2 will have higher priority - subscription2.setPriority(subscription.getPriority() + 1); + subscription2.setPriority(SubscriptionPriority.HIGH); // they conflict for cycle hour 8 subscription.getTime().setCycleTimes( @@ -389,7 +425,7 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { Subscription subscription2 = createSubscriptionThatFillsUpABucket(); // subscription2 will have higher priority - subscription2.setPriority(subscription.getPriority() + 1); + subscription2.setPriority(SubscriptionPriority.HIGH); // they conflict for cycle hour 8 subscription.getTime().setCycleTimes( @@ -419,8 +455,6 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { // Subscription starts out too big Subscription subscription = createSubscriptionThatFillsUpTwoBuckets(); - - // they conflict for cycle hour 8 subscription.getTime().setCycleTimes(Arrays.asList(Integer.valueOf(6))); List unscheduled = bandwidthManager @@ -432,6 +466,7 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { // Hey look, this subscription will fit now! subscription.setDataSetSize(subscription.getDataSetSize() / 2); + subscription.setUnscheduled(false); unscheduled = bandwidthManager.subscriptionUpdated(subscription); @@ -456,15 +491,14 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { public void testDetermineRequiredLatencyReturnsNecessaryLatency() throws SerializationException { - // Subscription starts out too big - Subscription subscription = createSubscriptionThatFillsUpTwoBuckets(); + Subscription subscription = createSubscriptionThatFillsUpTenBuckets(); subscription.getTime().setCycleTimes(Arrays.asList(Integer.valueOf(0))); subscription.setLatencyInMinutes(0); int requiredLatency = bandwidthManager .determineRequiredLatency(subscription); - assertEquals("The required latency was calculated incorrectly", 6, + assertEquals("The required latency was calculated incorrectly", 30, requiredLatency); } @@ -712,7 +746,7 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { final List bandwidthAllocations = bandwidthDao .getBandwidthAllocations(subscription.getRoute()); - assertEquals("Incorrect number of allocations found.", 4, + assertEquals("Incorrect number of allocations found.", 0, bandwidthAllocations.size()); sendDeletedSubscriptionEvent(subscription); @@ -745,7 +779,7 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { final List subscriptionDaos = bandwidthDao .getSubscriptionDao(subscription); - assertEquals("Incorrect number of subscription daos found.", 4, + assertEquals("Incorrect number of subscription daos found.", 0, subscriptionDaos.size()); sendDeletedSubscriptionEvent(subscription); diff --git a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthServiceIntTest.java b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthServiceIntTest.java index 31cab0bd6b..3af60822f1 100644 --- a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthServiceIntTest.java +++ b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthServiceIntTest.java @@ -47,6 +47,7 @@ import com.raytheon.uf.common.datadelivery.registry.AdhocSubscription; import com.raytheon.uf.common.datadelivery.registry.AdhocSubscriptionFixture; import com.raytheon.uf.common.datadelivery.registry.Network; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthAllocation; @@ -425,7 +426,7 @@ public class BandwidthServiceIntTest extends AbstractBandwidthManagerIntTest { Subscription subscription = createSubscriptionThatFillsUpTwoBuckets(); subscription.setLatencyInMinutes(6); - subscription.setPriority(2); + subscription.setPriority(SubscriptionPriority.HIGH); // Reserves a full bucket at 19700103 18:03:00 which fragments the // subscription to 19700103 18:00:00 and 18:06:00 @@ -538,9 +539,9 @@ public class BandwidthServiceIntTest extends AbstractBandwidthManagerIntTest { // Two subscriptions that will fill up a bucket exactly Subscription subscription = createSubscriptionThatFillsUpABucket(); - subscription.setPriority(2); + subscription.setPriority(SubscriptionPriority.NORMAL); Subscription subscription2 = createSubscriptionThatFillsUpABucket(); - subscription.setPriority(4); + subscription.setPriority(SubscriptionPriority.HIGH); // subscription2 will not be able to schedule for cycle hour 8 subscription.getTime().setCycleTimes( @@ -552,7 +553,8 @@ public class BandwidthServiceIntTest extends AbstractBandwidthManagerIntTest { service.schedule(subscription2); BandwidthGraphData graphData = service.getBandwidthGraphData(); - final Map priorityMap = graphData.getPriorityMap(); + final Map priorityMap = graphData + .getPriorityMap(); assertThat(priorityMap.get(subscription.getName()), is(equalTo(subscription.getPriority()))); diff --git a/tests/resources/META-INF/services/com.raytheon.uf.common.datadelivery.retrieval.util.LevelXmlWriter b/tests/resources/META-INF/services/com.raytheon.uf.common.datadelivery.retrieval.util.LevelXmlWriter deleted file mode 100644 index eec9b4aec4..0000000000 --- a/tests/resources/META-INF/services/com.raytheon.uf.common.datadelivery.retrieval.util.LevelXmlWriter +++ /dev/null @@ -1 +0,0 @@ -com.raytheon.uf.common.datadelivery.retrieval.util.NullXmlWriter \ No newline at end of file diff --git a/tests/resources/META-INF/services/com.raytheon.uf.common.datadelivery.retrieval.util.ParameterXmlWriter b/tests/resources/META-INF/services/com.raytheon.uf.common.datadelivery.retrieval.util.ParameterXmlWriter deleted file mode 100644 index eec9b4aec4..0000000000 --- a/tests/resources/META-INF/services/com.raytheon.uf.common.datadelivery.retrieval.util.ParameterXmlWriter +++ /dev/null @@ -1 +0,0 @@ -com.raytheon.uf.common.datadelivery.retrieval.util.NullXmlWriter \ No newline at end of file diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/registry/BaseSubscriptionFixture.java b/tests/unit/com/raytheon/uf/common/datadelivery/registry/BaseSubscriptionFixture.java index 93696f46c1..465a39abb1 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/registry/BaseSubscriptionFixture.java +++ b/tests/unit/com/raytheon/uf/common/datadelivery/registry/BaseSubscriptionFixture.java @@ -23,6 +23,7 @@ import java.util.Date; import java.util.Random; import com.google.common.collect.Lists; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.common.util.AbstractFixture; @@ -79,7 +80,7 @@ public abstract class BaseSubscriptionFixture extends subscription.setParameter(Lists. newArrayList()); // Same priority for all, individual tests needing to test specific // priorities should set it manually anyway - subscription.setPriority(1); + subscription.setPriority(SubscriptionPriority.NORMAL); subscription.setProvider(ProviderFixture.INSTANCE.get(seedValue) .getName()); subscription.setSubscriptionStart(subscription.getActivePeriodStart()); diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java b/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java index 12c01faea7..1e522d47ca 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java +++ b/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java @@ -76,6 +76,7 @@ public class OpenDapGriddedDataSetFixture extends obj.setDataSetName("dataSetName" + seedValue); obj.setDataSetType(DataType.GRID); obj.setForecastHours(CollectionUtil.asSet(0)); + obj.setTime(TimeFixture.INSTANCE.get(seedValue)); // TODO: ParameterFixture obj.setParameters(Collections. emptyMap()); obj.setProviderName(ProviderFixture.INSTANCE.get(seedValue).getName()); diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/registry/ParameterFixture.java b/tests/unit/com/raytheon/uf/common/datadelivery/registry/ParameterFixture.java index 1b1c4a8749..c9b5767533 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/registry/ParameterFixture.java +++ b/tests/unit/com/raytheon/uf/common/datadelivery/registry/ParameterFixture.java @@ -59,7 +59,6 @@ public class ParameterFixture extends AbstractFixture { obj.setBaseType("baseType" + seedValue); obj.setDataType(DataType.GRID); obj.setDefinition("definition" + seedValue); - obj.setEnsemble(0); obj.setFillValue("fillValue" + seedValue); obj.setLevels(LevelsFixture.INSTANCE.get(seedValue)); obj.setLevelType(Arrays.asList(DataLevelTypeFixture.INSTANCE diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/registry/ProviderTest.java b/tests/unit/com/raytheon/uf/common/datadelivery/registry/ProviderTest.java index 87b0c27f28..4efdc39352 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/registry/ProviderTest.java +++ b/tests/unit/com/raytheon/uf/common/datadelivery/registry/ProviderTest.java @@ -31,6 +31,8 @@ import javax.xml.bind.JAXBException; import org.junit.Test; +import com.raytheon.uf.common.time.domain.Durations; +import com.raytheon.uf.common.time.domain.api.IDuration; import com.raytheon.uf.edex.datadelivery.harvester.config.HarvesterConfig; import com.raytheon.uf.edex.datadelivery.harvester.config.HarvesterConfigFixture; @@ -53,30 +55,13 @@ import com.raytheon.uf.edex.datadelivery.harvester.config.HarvesterConfigFixture public class ProviderTest { - @Test - public void testSetPostedFileDelayAllowsSpacesSurrounding() { - Provider provider = new Provider(); - provider.setPostedFileDelay(" 2 MICROSECONDS "); - - assertEquals(2, provider.getPostedFileDelayValue()); - assertEquals(TimeUnit.MICROSECONDS, provider.getPostedFileDelayUnits()); - } - - @Test - public void testSetPostedFileDelayCanParseText() { - Provider provider = new Provider(); - provider.setPostedFileDelay("5 HOURS"); - - assertEquals(5, provider.getPostedFileDelayValue()); - assertEquals(TimeUnit.HOURS, provider.getPostedFileDelayUnits()); - } - @Test public void testSetPostedFileDelayIsCalledOnJaxbUnmarshall() throws JAXBException { HarvesterConfig config = HarvesterConfigFixture.INSTANCE.get(); Provider provider = config.getProvider(); - provider.setPostedFileDelay("3 DAYS"); + final IDuration originalDuration = Durations.of(3, TimeUnit.DAYS); + provider.setPostedFileDelay(originalDuration); Writer writer = new StringWriter(); JAXBContext ctx = JAXBContext.newInstance(HarvesterConfig.class); @@ -85,19 +70,6 @@ public class ProviderTest { HarvesterConfig restored = (HarvesterConfig) ctx.createUnmarshaller() .unmarshal(new StringReader(writer.toString())); Provider restoredProvider = restored.getProvider(); - assertEquals(3, restoredProvider.getPostedFileDelayValue()); - assertEquals(TimeUnit.DAYS, restoredProvider.getPostedFileDelayUnits()); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetPostedFileDelayThrowsExceptionOnInvalidUnits() { - Provider provider = new Provider(); - provider.setPostedFileDelay("5 HOUR"); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetPostedFileDelayThrowsExceptionOnValueLessThanZero() { - Provider provider = new Provider(); - provider.setPostedFileDelay("-1 DAYS"); + assertEquals(originalDuration, restoredProvider.getPostedFileDelay()); } } diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/registry/SubscriptionBuilder.java b/tests/unit/com/raytheon/uf/common/datadelivery/registry/SubscriptionBuilder.java index b43b0cf01c..181e54dae9 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/registry/SubscriptionBuilder.java +++ b/tests/unit/com/raytheon/uf/common/datadelivery/registry/SubscriptionBuilder.java @@ -21,6 +21,7 @@ package com.raytheon.uf.common.datadelivery.registry; import java.util.Date; +import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; import com.raytheon.uf.common.time.util.TimeUtil; @@ -73,7 +74,7 @@ public class SubscriptionBuilder { private String owner = "your_user"; - private int priority = 1; + private SubscriptionPriority priority = SubscriptionPriority.NORMAL; private Date subscriptionStart = TimeUtil.newDate(); @@ -256,7 +257,7 @@ public class SubscriptionBuilder { * @param priority * the priority to set */ - public SubscriptionBuilder withPriority(int priority) { + public SubscriptionBuilder withPriority(SubscriptionPriority priority) { this.priority = priority; return this; } diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/registry/handlers/GroupDefinitionServiceTest.java b/tests/unit/com/raytheon/uf/common/datadelivery/registry/handlers/GroupDefinitionServiceTest.java new file mode 100644 index 0000000000..0ef1a3125c --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/datadelivery/registry/handlers/GroupDefinitionServiceTest.java @@ -0,0 +1,135 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.datadelivery.registry.handlers; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.emptyCollectionOf; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; + +import com.raytheon.uf.common.datadelivery.registry.GroupDefinition; +import com.raytheon.uf.common.datadelivery.registry.GroupDefinitionServiceRequest; +import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.SubscriptionBuilder; +import com.raytheon.uf.common.datadelivery.service.GroupDefinitionService; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; +import com.raytheon.uf.common.registry.RegistryManagerTest; +import com.raytheon.uf.common.registry.handler.RegistryHandlerException; +import com.raytheon.uf.common.registry.handler.RegistryObjectHandlersUtil; +import com.raytheon.uf.edex.datadelivery.service.services.GroupDefinitionServiceHandler; + +/** + * Test {@link GroupDefinitionHandler}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2013 1441       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class GroupDefinitionServiceTest { + + private static final String GROUP_NAME = "someGroup"; + + private ISubscriptionHandler subscriptionHandler; + + private IGroupDefinitionHandler groupHandler; + + private final ISubscriptionNotificationService subscriptionNotificationService = mock(ISubscriptionNotificationService.class); + + private final GroupDefinitionService service = new GroupDefinitionService() { + @Override + protected Object sendRequest(GroupDefinitionServiceRequest request) + throws RegistryHandlerException { + try { + return new GroupDefinitionServiceHandler( + subscriptionNotificationService).handleRequest(request); + } catch (Exception e) { + throw new RegistryHandlerException(e); + } + } + }; + + private final GroupDefinition group = new GroupDefinition(); + + @Before + public void setUp() throws RegistryHandlerException { + RegistryObjectHandlersUtil.initMemory(); + RegistryManagerTest.setMockInstance(); + + subscriptionHandler = DataDeliveryHandlers.getSubscriptionHandler(); + groupHandler = DataDeliveryHandlers.getGroupDefinitionHandler(); + + group.setGroupName(GROUP_NAME); + groupHandler.store(group); + + Subscription subscription = new SubscriptionBuilder().withGroupName( + GROUP_NAME).build(); + Subscription subscription2 = new Subscription(subscription, "sub2"); + + subscriptionHandler.store(subscription); + subscriptionHandler.store(subscription2); + } + + @Test + public void deletingAGroupUpdatesSubscriptionsToNotHaveAGroupName() + throws RegistryHandlerException { + + service.deleteGroupDefinition(group); + + assertThat(subscriptionHandler.getByGroupName(GROUP_NAME), + is(emptyCollectionOf(Subscription.class))); + } + + @Test + public void deletingAGroupNotifiesOfSubscriptionUpdates() + throws RegistryHandlerException { + service.deleteGroupDefinition(group); + + verify(subscriptionNotificationService, times(2)) + .sendUpdatedSubscriptionNotification(any(Subscription.class), + anyString()); + } + + @Test + public void deletingAGroupDeletesTheGroup() throws RegistryHandlerException { + + service.deleteGroupDefinition(group); + + assertNull(groupHandler.getByName(GROUP_NAME)); + } + +} diff --git a/tests/unit/com/raytheon/uf/common/localization/TestPathManager.java b/tests/unit/com/raytheon/uf/common/localization/TestPathManager.java index 6967828aac..dbd105ca8e 100644 --- a/tests/unit/com/raytheon/uf/common/localization/TestPathManager.java +++ b/tests/unit/com/raytheon/uf/common/localization/TestPathManager.java @@ -40,6 +40,7 @@ import com.raytheon.uf.common.util.FileUtil; * ------------ ---------- ----------- -------------------------- * Jul 18, 2012 740 djohnson Initial creation * Oct 23, 2012 1286 djohnson Change to find more localization files. + * Jan 16, 2013 1487 djohnson Avoid adding new localization files to baseline utility directories. * * * @@ -131,21 +132,44 @@ public class TestPathManager extends PathManager { } if (foundFile == null - || !foundFile.exists() || foundFile.getAbsolutePath().startsWith( savedLocalizationFileDir.getAbsolutePath())) { return foundFile; } - // Make a copy in the savedFile folder, this way if any - // modifications are performed we don't mess with the file in - // the baseline + + File savedFile = createTestIsolatedVersionOfLocalizationFile( + context, fileName, foundFile); + return savedFile; + } + + /** + * Creates a test isolated version of the localization file. Allows the + * file to be written to, and changes to be read back, without affecting + * the baselined version of the file. + * + * @param context + * the context + * @param fileName + * the file path + * @param baselinedVersion + * the file reference + * @return + */ + private File createTestIsolatedVersionOfLocalizationFile( + LocalizationContext context, String fileName, File baselinedVersion) { File savedFileBaseDir = new File(savedLocalizationFileDir, context.toPath()); File savedFile = new File(savedFileBaseDir, fileName); savedFile.getParentFile().mkdirs(); try { - FileUtil.copyFile(foundFile, savedFile); + if (baselinedVersion.exists()) { + if (baselinedVersion.isDirectory()) { + FileUtil.copyDirectory(baselinedVersion, savedFile); + } else { + FileUtil.copyFile(baselinedVersion, savedFile); + } + } } catch (IOException e) { throw new RuntimeException(e); } diff --git a/tests/unit/com/raytheon/uf/common/registry/RegistryManagerTest.java b/tests/unit/com/raytheon/uf/common/registry/RegistryManagerTest.java index f71de52158..38ff11d5a7 100644 --- a/tests/unit/com/raytheon/uf/common/registry/RegistryManagerTest.java +++ b/tests/unit/com/raytheon/uf/common/registry/RegistryManagerTest.java @@ -19,8 +19,13 @@ **/ package com.raytheon.uf.common.registry; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.junit.Ignore; -import org.mockito.Mockito; /** * Allows setting a specific {@link RegistryHandler} instance for test purposes. @@ -48,9 +53,23 @@ public class RegistryManagerTest { * * @return the mock {@link RegistryHandler}. */ + @SuppressWarnings({ "rawtypes", "unchecked" }) public static RegistryHandler setMockInstance() { - RegistryHandler mock = Mockito.mock(RegistryHandler.class); + RegistryHandler mock = mock(RegistryHandler.class); RegistryManagerTest.setInstance(mock); + RegistryQueryResponse response = mock(RegistryQueryResponse.class); + when(response.getStatus()).thenReturn(OperationStatus.SUCCESS); + // Handles the responses for deletes, stores, and updates... + // TODO: Handle retrieving objects? + when(mock.removeObjects(any(RegistryQuery.class))).thenReturn(response); + when(mock.removeObjects(anyString(), anyList())).thenReturn(response); + when(mock.removeObjects(anyString(), any(RegistryQuery.class))) + .thenReturn(response); + when(mock.storeObject(any())).thenReturn(response); + when(mock.storeOrReplaceObject(any())).thenReturn(response); + when(mock.removeObjects(anyString(), any(RegistryQuery.class))) + .thenReturn(response); + return mock; } diff --git a/tests/unit/com/raytheon/uf/common/stats/data/DataPointTest.java b/tests/unit/com/raytheon/uf/common/stats/data/DataPointTest.java index 675fa61bb1..e65a4d3530 100644 --- a/tests/unit/com/raytheon/uf/common/stats/data/DataPointTest.java +++ b/tests/unit/com/raytheon/uf/common/stats/data/DataPointTest.java @@ -10,7 +10,7 @@ import java.util.TimeZone; import org.junit.Test; import com.raytheon.uf.common.stats.AggregateRecord; -import com.raytheon.uf.common.stats.util.DataViewUtils; +import com.raytheon.uf.common.stats.util.DataView; public class DataPointTest { private final String eventType = "com.raytheon.uf.common.stats.ProcessEvent"; @@ -38,7 +38,7 @@ public class DataPointTest { assertEquals("Count does not match", expectedCount, point.getCount(), 0); assertEquals("Count does not match", expectedCount, - point.getValue(DataViewUtils.DataView.COUNT.getView()), 0); + point.getValue(DataView.COUNT), 0); } @Test @@ -60,7 +60,7 @@ public class DataPointTest { assertEquals("Sum does not match", expectedSum, point.getSum(), 0); assertEquals("Sum does not match", expectedSum, - point.getValue(DataViewUtils.DataView.SUM.getView()), 0); + point.getValue(DataView.SUM), 0); } @Test @@ -82,7 +82,7 @@ public class DataPointTest { assertEquals("Min does not match", expectedMin, point.getMin(), 0); assertEquals("Min does not match", expectedMin, - point.getValue(DataViewUtils.DataView.MIN.getView()), 0); + point.getValue(DataView.MIN), 0); } @Test @@ -104,7 +104,7 @@ public class DataPointTest { assertEquals("Max does not match", expectedMax, point.getMax(), 0); assertEquals("Max does not match", expectedMax, - point.getValue(DataViewUtils.DataView.MAX.getView()), 0); + point.getValue(DataView.MAX), 0); } @Test @@ -128,7 +128,7 @@ public class DataPointTest { assertEquals("Avg does not match", expectedAvg, point.getAvg(), 0.25); assertEquals("Avg does not match", expectedAvg, - point.getValue(DataViewUtils.DataView.AVG.getView()), 0.25); + point.getValue(DataView.AVG), 0.25); } // Build the Aggregate records diff --git a/tests/unit/com/raytheon/uf/common/stats/data/StatsDataTest.java b/tests/unit/com/raytheon/uf/common/stats/data/StatsDataTest.java index a809993eff..39f11bb83d 100644 --- a/tests/unit/com/raytheon/uf/common/stats/data/StatsDataTest.java +++ b/tests/unit/com/raytheon/uf/common/stats/data/StatsDataTest.java @@ -17,7 +17,9 @@ import com.raytheon.uf.common.time.util.TimeUtil; public class StatsDataTest { private final String eventType = "com.raytheon.uf.common.stats.ProcessEvent"; + private final String field = "processingTime"; + private final String grouping = "pluginName:obs"; final Map bins = new TreeMap(); @@ -41,7 +43,8 @@ public class StatsDataTest { UnitUtils unitUtils = new UnitUtils(eventType, field); unitUtils.setDisplayUnit("ms"); - StatsData statsData = new StatsData("key", TimeUtil.MILLIS_PER_MINUTE, null, unitUtils); + StatsData statsData = new StatsData("key", TimeUtil.MILLIS_PER_MINUTE, + null); statsData.setBins(bins); statsData.addRecord(records.get(0)); statsData.addRecord(records.get(1)); @@ -50,11 +53,10 @@ public class StatsDataTest { List pointList = statsData.getData(); int expectedPointCount = 2; - assertEquals("Point Counts differ", expectedPointCount, pointList.size(), 0); + assertEquals("Point Counts differ", expectedPointCount, + pointList.size(), 0); } - - // Build the Aggregate records private List getTestRecords() { List records = new ArrayList(); diff --git a/tests/unit/com/raytheon/uf/common/stats/util/UnitUtilsTest.java b/tests/unit/com/raytheon/uf/common/stats/util/UnitUtilsTest.java new file mode 100644 index 0000000000..3515ba3021 --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/stats/util/UnitUtilsTest.java @@ -0,0 +1,179 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.stats.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.raytheon.uf.common.stats.ProcessEvent; +import com.raytheon.uf.common.stats.util.UnitUtils.TimeConversion; +import com.raytheon.uf.common.stats.util.UnitUtils.UnitTypes; +import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.units.DataSizeUnit; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 17, 2013   1357      mpduff     Initial creation
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +public class UnitUtilsTest { + + private static final String EVENT_TYPE = ProcessEvent.class.getName(); + + private static final String DATA_TYPE = "processingTime"; + + @Test + public void testConvertBytesToBytes() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(DataSizeUnit.BYTE.getUnit()); + uu.setDisplayUnit(DataSizeUnit.BYTE.getUnit()); + + double value = uu.convertDataSizeValue(DataSizeUnit.BYTE, 100); + + assertEquals(100, value, 0); + } + + @Test + public void testConvertBytesToKb() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(DataSizeUnit.BYTE.getUnit()); + uu.setDisplayUnit(DataSizeUnit.KB.getUnit()); + + double value = uu.convertDataSizeValue(DataSizeUnit.BYTE, 1024); + + assertEquals(1, value, 0); + } + + @Test + public void testConvertBytesToMb() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(DataSizeUnit.BYTE.getUnit()); + uu.setDisplayUnit(DataSizeUnit.MB.getUnit()); + + double value = uu.convertDataSizeValue(DataSizeUnit.BYTE, 1048576); + + assertEquals(1, value, 0); + } + + @Test + public void testConvertValueFromMsToSecond() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(TimeConversion.MS.getDataUnit()); + uu.setDisplayUnit(TimeConversion.Second.getDataUnit()); + + double value = uu.convertTimeValue(TimeConversion.MS, + TimeUtil.MILLIS_PER_SECOND * 3); + + assertEquals(3, value, 0); + } + + @Test + public void testConvertValueFromMsToMinute() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(TimeConversion.MS.getDataUnit()); + uu.setDisplayUnit(TimeConversion.Minute.getDataUnit()); + + double value = uu.convertTimeValue(TimeConversion.MS, + TimeUtil.MILLIS_PER_MINUTE * 2); + + assertEquals(2, value, 0); + } + + @Test + public void testConvertValueFromMsToHours() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(TimeConversion.MS.getDataUnit()); + uu.setDisplayUnit(TimeConversion.Hour.getDataUnit()); + + double value = uu.convertTimeValue(TimeConversion.MS, + TimeUtil.MILLIS_PER_HOUR); + + assertEquals(1, value, 0); + } + + @Test + public void testConvertValueFromHoursToMs() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(TimeConversion.Hour.getDataUnit()); + uu.setDisplayUnit(TimeConversion.MS.getDataUnit()); + + double value = uu.convertTimeValue(TimeConversion.Hour, 1); + + assertEquals(TimeUtil.MILLIS_PER_HOUR, value, 0); + } + + @Test + public void testVerifyDisplayUnitIsTime() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(TimeConversion.Hour.getDataUnit()); + uu.setDisplayUnit(TimeConversion.MS.getDataUnit()); + + UnitTypes type = uu.getUnitType(); + + assertEquals(UnitTypes.TIME, type); + } + + @Test + public void testVerifyDisplayUnitIsSize() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(DataSizeUnit.KB.getUnit()); + uu.setDisplayUnit(DataSizeUnit.MB.getUnit()); + + UnitTypes type = uu.getUnitType(); + + assertEquals(UnitTypes.DATA_SIZE, type); + } + + @Test + public void testConvertValueToSec() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(TimeConversion.MS.getDataUnit()); + uu.setDisplayUnit(TimeConversion.Second.getDataUnit()); + + double value = uu.convertValue(TimeUtil.MILLIS_PER_SECOND * 3); + + assertEquals(3, value, 0); + } + + @Test + public void testConvertValueToMinute() { + UnitUtils uu = new UnitUtils(EVENT_TYPE, DATA_TYPE); + uu.setUnitType(TimeConversion.MS.getDataUnit()); + uu.setDisplayUnit(TimeConversion.Minute.getDataUnit()); + + double value = uu.convertValue(TimeUtil.MILLIS_PER_MINUTE * 3); + + assertEquals(3, value, 0); + } + +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/DurationTest.java b/tests/unit/com/raytheon/uf/common/time/domain/DurationTest.java new file mode 100644 index 0000000000..8ab3593e2d --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/DurationTest.java @@ -0,0 +1,302 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import static com.raytheon.uf.common.serialization.SerializationUtil.transformFromThrift; +import static com.raytheon.uf.common.serialization.SerializationUtil.transformToThrift; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.xml.bind.JAXBException; + +import org.junit.Test; + +import com.raytheon.uf.common.serialization.JAXBManager; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.time.domain.api.IDuration; +import com.raytheon.uf.common.util.TestUtil; + +/** + * Test {@link Duration}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 10, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class DurationTest { + + private static final long TWO_DAYS_IN_NANOS = TimeUnit.DAYS.toNanos(2); + + private static final long TWO_DAYS_IN_MICROS = TimeUnit.DAYS.toMicros(2); + + private static final long TWO_DAYS_IN_MILLIS = TimeUnit.DAYS.toMillis(2); + + private static final long TWO_DAYS_IN_SECONDS = TimeUnit.DAYS.toSeconds(2); + + private static final long TWO_DAYS_IN_MINUTES = TimeUnit.DAYS.toMinutes(2); + + private static final long TWO_DAYS_IN_HOURS = TimeUnit.DAYS.toHours(2); + + private static final long TWO_DAYS_IN_DAYS = TimeUnit.DAYS.toDays(2); + + @Test + public void testNanosecondsConvertToEntireRange() { + IDuration duration = new Duration(TWO_DAYS_IN_NANOS, + TimeUnit.NANOSECONDS); + + assertThat(TWO_DAYS_IN_NANOS, is(equalTo(duration.getNanos()))); + assertThat(TWO_DAYS_IN_MICROS, is(equalTo(duration.getMicros()))); + assertThat(TWO_DAYS_IN_MILLIS, is(equalTo(duration.getMillis()))); + assertThat(TWO_DAYS_IN_SECONDS, is(equalTo(duration.getSeconds()))); + assertThat(TWO_DAYS_IN_MINUTES, is(equalTo(duration.getMinutes()))); + assertThat(TWO_DAYS_IN_HOURS, is(equalTo(duration.getHours()))); + assertThat(TWO_DAYS_IN_DAYS, is(equalTo(duration.getDays()))); + } + + @Test + public void testNanosecondsConvertToZeroWhenNotEnoughOfTargetUnit() { + final long startValue = 5L; + IDuration duration = new Duration(startValue, TimeUnit.NANOSECONDS); + + assertThat(startValue, is(equalTo(duration.getNanos()))); + assertThat(0L, is(equalTo(duration.getMicros()))); + assertThat(0L, is(equalTo(duration.getMillis()))); + assertThat(0L, is(equalTo(duration.getSeconds()))); + assertThat(0L, is(equalTo(duration.getMinutes()))); + assertThat(0L, is(equalTo(duration.getHours()))); + assertThat(0L, is(equalTo(duration.getDays()))); + } + + @Test + public void testMicrosecondsConvertToEntireRange() { + IDuration duration = new Duration(TWO_DAYS_IN_MICROS, + TimeUnit.MICROSECONDS); + + assertThat(TWO_DAYS_IN_NANOS, is(equalTo(duration.getNanos()))); + assertThat(TWO_DAYS_IN_MICROS, is(equalTo(duration.getMicros()))); + assertThat(TWO_DAYS_IN_MILLIS, is(equalTo(duration.getMillis()))); + assertThat(TWO_DAYS_IN_SECONDS, is(equalTo(duration.getSeconds()))); + assertThat(TWO_DAYS_IN_MINUTES, is(equalTo(duration.getMinutes()))); + assertThat(TWO_DAYS_IN_HOURS, is(equalTo(duration.getHours()))); + assertThat(TWO_DAYS_IN_DAYS, is(equalTo(duration.getDays()))); + } + + @Test + public void testMicrosecondsConvertToZeroWhenNotEnoughOfTargetUnit() { + final long startValue = 5L; + IDuration duration = new Duration(startValue, TimeUnit.MICROSECONDS); + + assertThat(startValue, is(equalTo(duration.getMicros()))); + assertThat(0L, is(equalTo(duration.getMillis()))); + assertThat(0L, is(equalTo(duration.getSeconds()))); + assertThat(0L, is(equalTo(duration.getMinutes()))); + assertThat(0L, is(equalTo(duration.getHours()))); + assertThat(0L, is(equalTo(duration.getDays()))); + } + + @Test + public void testMillisecondsConvertToEntireRange() { + IDuration duration = new Duration(TWO_DAYS_IN_MILLIS, + TimeUnit.MILLISECONDS); + + assertThat(TWO_DAYS_IN_NANOS, is(equalTo(duration.getNanos()))); + assertThat(TWO_DAYS_IN_MICROS, is(equalTo(duration.getMicros()))); + assertThat(TWO_DAYS_IN_MILLIS, is(equalTo(duration.getMillis()))); + assertThat(TWO_DAYS_IN_SECONDS, is(equalTo(duration.getSeconds()))); + assertThat(TWO_DAYS_IN_MINUTES, is(equalTo(duration.getMinutes()))); + assertThat(TWO_DAYS_IN_HOURS, is(equalTo(duration.getHours()))); + assertThat(TWO_DAYS_IN_DAYS, is(equalTo(duration.getDays()))); + } + + @Test + public void testMillisecondsConvertToZeroWhenNotEnoughOfTargetUnit() { + final long startValue = 5L; + IDuration duration = new Duration(startValue, TimeUnit.MILLISECONDS); + + assertThat(startValue, is(equalTo(duration.getMillis()))); + assertThat(0L, is(equalTo(duration.getSeconds()))); + assertThat(0L, is(equalTo(duration.getMinutes()))); + assertThat(0L, is(equalTo(duration.getHours()))); + assertThat(0L, is(equalTo(duration.getDays()))); + } + + @Test + public void testSecondsConvertToEntireRange() { + IDuration duration = new Duration(TWO_DAYS_IN_SECONDS, TimeUnit.SECONDS); + + assertThat(TWO_DAYS_IN_NANOS, is(equalTo(duration.getNanos()))); + assertThat(TWO_DAYS_IN_MICROS, is(equalTo(duration.getMicros()))); + assertThat(TWO_DAYS_IN_MILLIS, is(equalTo(duration.getMillis()))); + assertThat(TWO_DAYS_IN_SECONDS, is(equalTo(duration.getSeconds()))); + assertThat(TWO_DAYS_IN_MINUTES, is(equalTo(duration.getMinutes()))); + assertThat(TWO_DAYS_IN_HOURS, is(equalTo(duration.getHours()))); + assertThat(TWO_DAYS_IN_DAYS, is(equalTo(duration.getDays()))); + } + + @Test + public void testSecondsConvertToZeroWhenNotEnoughOfTargetUnit() { + final long startValue = 5L; + IDuration duration = new Duration(startValue, TimeUnit.SECONDS); + + assertThat(startValue, is(equalTo(duration.getSeconds()))); + assertThat(0L, is(equalTo(duration.getMinutes()))); + assertThat(0L, is(equalTo(duration.getHours()))); + assertThat(0L, is(equalTo(duration.getDays()))); + } + + @Test + public void testMinutesConvertToEntireRange() { + IDuration duration = new Duration(TWO_DAYS_IN_MINUTES, TimeUnit.MINUTES); + + assertThat(TWO_DAYS_IN_NANOS, is(equalTo(duration.getNanos()))); + assertThat(TWO_DAYS_IN_MICROS, is(equalTo(duration.getMicros()))); + assertThat(TWO_DAYS_IN_MILLIS, is(equalTo(duration.getMillis()))); + assertThat(TWO_DAYS_IN_SECONDS, is(equalTo(duration.getSeconds()))); + assertThat(TWO_DAYS_IN_MINUTES, is(equalTo(duration.getMinutes()))); + assertThat(TWO_DAYS_IN_HOURS, is(equalTo(duration.getHours()))); + assertThat(TWO_DAYS_IN_DAYS, is(equalTo(duration.getDays()))); + } + + @Test + public void testMinutesConvertToZeroWhenNotEnoughOfTargetUnit() { + final long startValue = 5L; + IDuration duration = new Duration(startValue, TimeUnit.MINUTES); + + assertThat(startValue, is(equalTo(duration.getMinutes()))); + assertThat(0L, is(equalTo(duration.getHours()))); + assertThat(0L, is(equalTo(duration.getDays()))); + } + + @Test + public void testHoursConvertToEntireRange() { + IDuration duration = new Duration(TWO_DAYS_IN_HOURS, TimeUnit.HOURS); + + assertThat(TWO_DAYS_IN_NANOS, is(equalTo(duration.getNanos()))); + assertThat(TWO_DAYS_IN_MICROS, is(equalTo(duration.getMicros()))); + assertThat(TWO_DAYS_IN_MILLIS, is(equalTo(duration.getMillis()))); + assertThat(TWO_DAYS_IN_SECONDS, is(equalTo(duration.getSeconds()))); + assertThat(TWO_DAYS_IN_MINUTES, is(equalTo(duration.getMinutes()))); + assertThat(TWO_DAYS_IN_HOURS, is(equalTo(duration.getHours()))); + assertThat(TWO_DAYS_IN_DAYS, is(equalTo(duration.getDays()))); + } + + @Test + public void testHoursConvertToZeroWhenNotEnoughOfTargetUnit() { + final long startValue = 5L; + IDuration duration = new Duration(startValue, TimeUnit.HOURS); + + assertThat(startValue, is(equalTo(duration.getHours()))); + assertThat(0L, is(equalTo(duration.getDays()))); + } + + @Test + public void testDaysConvertToEntireRange() { + IDuration duration = new Duration(TWO_DAYS_IN_DAYS, TimeUnit.DAYS); + + assertThat(TWO_DAYS_IN_NANOS, is(equalTo(duration.getNanos()))); + assertThat(TWO_DAYS_IN_MICROS, is(equalTo(duration.getMicros()))); + assertThat(TWO_DAYS_IN_MILLIS, is(equalTo(duration.getMillis()))); + assertThat(TWO_DAYS_IN_SECONDS, is(equalTo(duration.getSeconds()))); + assertThat(TWO_DAYS_IN_MINUTES, is(equalTo(duration.getMinutes()))); + assertThat(TWO_DAYS_IN_HOURS, is(equalTo(duration.getHours()))); + assertThat(TWO_DAYS_IN_DAYS, is(equalTo(duration.getDays()))); + } + + @Test + public void testAddDurationReturnsCorrectAmount() { + IDuration dur1 = new Duration(2, TimeUnit.HOURS); + IDuration dur2 = new Duration(2, TimeUnit.DAYS); + + assertThat(new Duration(50, TimeUnit.HOURS), + is(equalTo(dur1.plus(dur2)))); + } + + @Test + public void testSubtractDurationReturnsCorrectAmount() { + IDuration dur1 = new Duration(2, TimeUnit.DAYS); + IDuration dur2 = new Duration(2, TimeUnit.HOURS); + + assertThat(new Duration(46, TimeUnit.HOURS), + is(equalTo(dur1.minus(dur2)))); + } + + @Test + public void testConversionToAndFromDynamicSerialize() + throws SerializationException { + IDuration original = new Duration(2, TimeUnit.DAYS); + UsesDuration usesDuration = new UsesDuration(); + usesDuration.setDuration(original); + + IDuration restored = transformFromThrift(UsesDuration.class, + transformToThrift(usesDuration)).getDuration(); + + assertThat(restored, is(equalTo(original))); + } + + @Test + public void testConversionToAndFromJaxb() throws SerializationException, + JAXBException { + IDuration original = new Duration(2, TimeUnit.DAYS); + UsesDuration usesDuration = new UsesDuration(); + usesDuration.setDuration(original); + + JAXBManager manager = new JAXBManager(UsesDuration.class); + final String xml = manager.marshalToXml(usesDuration); + + IDuration restored = ((UsesDuration) manager.unmarshalFromXml(xml)) + .getDuration(); + + assertThat(restored, is(equalTo(original))); + } + + @Test + public void testEqualsAndHashcodeContract() { + IDuration objectUnderTest = Durations.of(TWO_DAYS_IN_DAYS, + TimeUnit.DAYS); + + List equalObjects = Arrays.asList( + Durations.of(TWO_DAYS_IN_HOURS, TimeUnit.HOURS), + Durations.of(TWO_DAYS_IN_MINUTES, TimeUnit.MINUTES), + Durations.of(TWO_DAYS_IN_SECONDS, TimeUnit.SECONDS)); + + List unequalObjects = Arrays.asList( + Durations.of(TWO_DAYS_IN_HOURS + 1, TimeUnit.HOURS), + Durations.of(TWO_DAYS_IN_MINUTES + 1, TimeUnit.MINUTES), + Durations.of(TWO_DAYS_IN_SECONDS + 1, TimeUnit.SECONDS)); + + TestUtil.assertEqualsAndHashcodeContract(objectUnderTest, equalObjects, + unequalObjects); + } +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/DurationsTest.java b/tests/unit/com/raytheon/uf/common/time/domain/DurationsTest.java new file mode 100644 index 0000000000..80b6d244e2 --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/DurationsTest.java @@ -0,0 +1,94 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.concurrent.TimeUnit; + +import org.junit.Test; + +import com.raytheon.uf.common.time.domain.api.IDuration; + +/** + * Test {@link Durations}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 11, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class DurationsTest { + + @Test + public void testParseFromString() { + IDuration duration = Durations.fromString("3 SECONDS"); + + assertThat(duration, is(equalTo(Durations.of(3, TimeUnit.SECONDS)))); + } + + @Test(expected = IllegalArgumentException.class) + public void testUnparseableStringThrowsException() { + Durations.fromString("unparseable"); + } + + @Test + public void testToStringWritesOutLargestUnitNotLosingPrecision() { + final String original = "3 SECONDS"; + IDuration duration = Durations.fromString(original); + + assertThat(Durations.toString(duration), is(equalTo(original))); + } + + @Test + public void testToStringForSmallestUnit() { + final String original = "1 NANOSECONDS"; + IDuration duration = Durations.fromString(original); + + assertThat(Durations.toString(duration), is(equalTo(original))); + } + + @Test + public void testToStringForLargestUnit() { + final String original = "7 DAYS"; + IDuration duration = Durations.fromString(original); + + assertThat(Durations.toString(duration), is(equalTo(original))); + } + + @Test + public void test128MinutesDoesNotUseHours() { + final String original = "128 MINUTES"; + IDuration duration = Durations.fromString(original); + + assertThat(Durations.toString(duration), is(equalTo(original))); + } +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/TimeIntervalTest.java b/tests/unit/com/raytheon/uf/common/time/domain/TimeIntervalTest.java new file mode 100644 index 0000000000..ea67921f7d --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/TimeIntervalTest.java @@ -0,0 +1,157 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import static com.raytheon.uf.common.serialization.SerializationUtil.transformFromThrift; +import static com.raytheon.uf.common.serialization.SerializationUtil.transformToThrift; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.xml.bind.JAXBException; + +import org.junit.Test; + +import com.raytheon.uf.common.serialization.JAXBManager; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.time.domain.api.ITimeInterval; +import com.raytheon.uf.common.time.domain.api.ITimePoint; +import com.raytheon.uf.common.util.TestUtil; + +/** + * Test {@link TimeInterval}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class TimeIntervalTest { + + private final ITimePoint intervalStart = TimePoints.fromMillis(100L); + + private final ITimePoint intervalEnd = TimePoints.fromMillis(500L); + + private final ITimeInterval interval = new TimeInterval(intervalStart, + intervalEnd); + + @Test + public void testConversionToAndFromDynamicSerialize() + throws SerializationException { + UsesTimeInterval usesTimeInterval = new UsesTimeInterval(); + usesTimeInterval.setTimeInterval(interval); + + ITimeInterval restored = transformFromThrift(UsesTimeInterval.class, + transformToThrift(usesTimeInterval)).getTimeInterval(); + + assertThat(restored, is(equalTo(interval))); + } + + @Test + public void testConversionToAndFromJaxb() throws SerializationException, + JAXBException { + UsesTimeInterval usesTimeInterval = new UsesTimeInterval(); + usesTimeInterval.setTimeInterval(interval); + + JAXBManager manager = new JAXBManager(UsesTimeInterval.class); + final String xml = manager.marshalToXml(usesTimeInterval); + + ITimeInterval restored = ((UsesTimeInterval) manager + .unmarshalFromXml(xml)).getTimeInterval(); + + assertThat(restored, is(equalTo(interval))); + } + + @Test + public void testGetStartReturnsCorrectTimePoint() { + assertThat(interval.getStart(), is(equalTo(intervalStart))); + } + + @Test + public void testGetEndReturnsCorrectTimePoint() { + assertThat(interval.getEnd(), is(equalTo(intervalEnd))); + } + + @Test + public void testContainsTimePointReturnsTrueForMidPointWithinInterval() { + final ITimePoint withinInterval = TimePoints.fromMillis((intervalStart + .asMilliseconds() + intervalEnd.asMilliseconds()) / 2); + + assertTrue( + "The interval should have returned true for a time point contained in it!", + interval.containsTimePoint(withinInterval)); + } + + @Test + public void testContainsTimePointReturnsTrueForIntervalStart() { + assertTrue( + "The interval should have returned true for a time point contained in it!", + interval.containsTimePoint(intervalStart)); + } + + @Test + public void testContainsTimePointReturnsTrueForIntervalEnd() { + assertTrue( + "The interval should have returned true for a time point contained in it!", + interval.containsTimePoint(intervalEnd)); + } + + @Test + public void testGetDurationReturnsCorrectAmount() { + assertThat(interval.getDuration(), is(equalTo(Durations.of( + intervalEnd.asMilliseconds() - intervalStart.asMilliseconds(), + TimeUnit.MILLISECONDS)))); + } + + @Test + public void testEqualsAndHashcodeContract() { + ITimeInterval sameInterval = new TimeInterval( + TimePoints.fromMillis(intervalStart.asMilliseconds()), + TimePoints.fromMillis(intervalEnd.asMilliseconds())); + List equalObjects = Arrays + . asList(sameInterval); + + ITimeInterval startOneMillisecondEarlier = new TimeInterval( + TimePoints.fromMillis(intervalStart.asMilliseconds() - 1L), + TimePoints.fromMillis(intervalEnd.asMilliseconds())); + ITimeInterval endOneMillisecondLater = new TimeInterval( + TimePoints.fromMillis(intervalStart.asMilliseconds()), + TimePoints.fromMillis(intervalEnd.asMilliseconds() + 1L)); + + List unequalObjects = Arrays. asList( + startOneMillisecondEarlier, endOneMillisecondLater); + + TestUtil.assertEqualsAndHashcodeContract(interval, equalObjects, + unequalObjects); + } +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/TimeIntervalsTest.java b/tests/unit/com/raytheon/uf/common/time/domain/TimeIntervalsTest.java new file mode 100644 index 0000000000..872b010043 --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/TimeIntervalsTest.java @@ -0,0 +1,48 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import org.junit.Test; + +/** + * Test {@link TimeIntervals}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class TimeIntervalsTest { + + @Test(expected = IllegalArgumentException.class) + public void testEndCantBeBeforeStart() { + TimeIntervals.fromTimePoints(TimePoints.fromMillis(20L), + TimePoints.fromMillis(10L)); + } + +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/TimePointTest.java b/tests/unit/com/raytheon/uf/common/time/domain/TimePointTest.java new file mode 100644 index 0000000000..ac2ab6b50e --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/TimePointTest.java @@ -0,0 +1,202 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import static com.raytheon.uf.common.serialization.SerializationUtil.transformFromThrift; +import static com.raytheon.uf.common.serialization.SerializationUtil.transformToThrift; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import javax.xml.bind.JAXBException; + +import org.junit.Test; + +import com.raytheon.uf.common.serialization.JAXBManager; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.time.domain.api.ITimeInterval; +import com.raytheon.uf.common.time.domain.api.ITimePoint; +import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.util.TestUtil; + +/** + * Test {@link TimePoint}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class TimePointTest { + + private final ITimePoint earlierPoint = new TimePoint(1L); + + private final ITimePoint laterPoint = new TimePoint(2L); + + private final ITimePoint sameAsEarlierPoint = new TimePoint(earlierPoint); + + @Test + public void testConversionToAndFromDynamicSerialize() + throws SerializationException { + UsesTimePoint usesTimePoint = new UsesTimePoint(); + usesTimePoint.setTimePoint(laterPoint); + + ITimePoint restored = transformFromThrift(UsesTimePoint.class, + transformToThrift(usesTimePoint)).getTimePoint(); + + assertThat(restored, is(equalTo(laterPoint))); + } + + @Test + public void testConversionToAndFromJaxb() throws SerializationException, + JAXBException { + UsesTimePoint usesTimePoint = new UsesTimePoint(); + usesTimePoint.setTimePoint(laterPoint); + + JAXBManager manager = new JAXBManager(UsesTimePoint.class); + final String xml = manager.marshalToXml(usesTimePoint); + + ITimePoint restored = ((UsesTimePoint) manager.unmarshalFromXml(xml)) + .getTimePoint(); + + assertThat(restored, is(equalTo(laterPoint))); + } + + @Test + public void testAsDateReturnsSameInstance() { + Date date = new Date(); + + TimePoint timePoint = new TimePoint(date.getTime()); + + assertThat(timePoint.asDate(), is(equalTo(date))); + } + + @Test + public void testAsMillisecondsReturnsOriginalValue() { + final long originalMillis = TimeUtil.currentTimeMillis(); + TimePoint timePoint = new TimePoint(originalMillis); + + assertThat(timePoint.asMilliseconds(), is(equalTo(originalMillis))); + } + + @Test + public void testIsAfterReturnsTrueWhenLater() { + assertTrue("The later point should have been recognized as later!", + laterPoint.isAfter(earlierPoint)); + } + + @Test + public void testIsAfterReturnsFalseWhenEarlier() { + assertFalse( + "The earlier point should have been recognized as not later!", + earlierPoint.isAfter(laterPoint)); + } + + @Test + public void testIsAfterReturnsFalseWhenSameTime() { + assertFalse( + "The earlier point should have been recognized as not later!", + sameAsEarlierPoint.isAfter(laterPoint)); + } + + @Test + public void testIsBeforeReturnsTrueWhenEarlier() { + assertTrue("The earlier point should have been recognized as earlier!", + earlierPoint.isBefore(laterPoint)); + } + + @Test + public void testIsBeforeReturnsFalseWhenLater() { + assertFalse( + "The later point should have been recognized as not earlier!", + laterPoint.isBefore(earlierPoint)); + } + + @Test + public void testIsBeforeReturnsFalseWhenSameTime() { + assertFalse( + "The same time point should have been recognized as not earlier!", + sameAsEarlierPoint.isBefore(earlierPoint)); + } + + @Test + public void testIsSameReturnsFalseWhenEarlier() { + assertFalse("The earlier point should not have been the same!", + earlierPoint.isSame(laterPoint)); + } + + @Test + public void testIsSameReturnsFalseWhenLater() { + assertFalse("The later point should not have been the same!", + laterPoint.isSame(earlierPoint)); + } + + @Test + public void testIsSameReturnsTrueWhenSameTime() { + assertTrue( + "The same time point should have been recognized as the same time!", + sameAsEarlierPoint.isSame(earlierPoint)); + } + + @Test + public void testIsWithinReturnsTrueForTimeIntervalThatContainsIt() { + ITimeInterval interval = TimeIntervals.fromTimePoints(earlierPoint, + laterPoint); + assertTrue( + "The time point should have returned true for being within the interval", + earlierPoint.isWithin(interval)); + } + + @Test + public void testIsWithinReturnsFalseForTimeIntervalThatDoesntContainIt() { + ITimeInterval interval = TimeIntervals.fromTimePoints(earlierPoint, + laterPoint); + + assertFalse( + "The time point should have returned false for being within the interval", + new TimePoint(earlierPoint.asMilliseconds() - 1L) + .isWithin(interval)); + } + + @Test + public void testEqualsAndHashcodeContract() { + List equalObjects = Arrays.asList(sameAsEarlierPoint); + List unequalObjects = Arrays.asList(laterPoint, + TimePoints.now()); + + TestUtil.assertEqualsAndHashcodeContract(earlierPoint, equalObjects, + unequalObjects); + } +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/TimePointsTest.java b/tests/unit/com/raytheon/uf/common/time/domain/TimePointsTest.java new file mode 100644 index 0000000000..86b72b8036 --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/TimePointsTest.java @@ -0,0 +1,70 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.time.util.TimeUtilTest; + +/** + * Test {@link TimePoints}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class TimePointsTest { + + @Before + public void setUp() { + TimeUtilTest.freezeTime(); + } + + @After + public void tearDown() { + TimeUtilTest.resumeTime(); + } + + @Test + public void testNowReturnsCurrentTime() { + long expectedTime = TimeUtil.currentTimeMillis(); + + assertThat(TimePoints.now(), + is(equalTo(TimePoints.fromMillis(expectedTime)))); + } + +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/UsesDuration.java b/tests/unit/com/raytheon/uf/common/time/domain/UsesDuration.java new file mode 100644 index 0000000000..c2e6df58db --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/UsesDuration.java @@ -0,0 +1,75 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.junit.Ignore; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.time.domain.api.IDuration; + +/** + * Uses an {@link IDuration}. Used by {@link DurationTest} to verify Jaxb + * interoperability. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 11, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@Ignore +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class UsesDuration { + + @DynamicSerializeElement + @XmlElement + private IDuration duration; + + /** + * @return the duration + */ + public IDuration getDuration() { + return duration; + } + + /** + * @param duration + * the duration to set + */ + public void setDuration(IDuration duration) { + this.duration = duration; + } + +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/UsesTimeInterval.java b/tests/unit/com/raytheon/uf/common/time/domain/UsesTimeInterval.java new file mode 100644 index 0000000000..c381fc9a6c --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/UsesTimeInterval.java @@ -0,0 +1,75 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.junit.Ignore; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.time.domain.api.ITimeInterval; + +/** + * Uses an {@link ITimeInterval}. Used by {@link TimeIntervalTest} to verify + * Jaxb interoperability. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 11, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@Ignore +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class UsesTimeInterval { + + @DynamicSerializeElement + @XmlElement + private ITimeInterval timeInterval; + + /** + * @return the timeInterval + */ + public ITimeInterval getTimeInterval() { + return timeInterval; + } + + /** + * @param timeInterval + * the timeInterval to set + */ + public void setTimeInterval(ITimeInterval timeInterval) { + this.timeInterval = timeInterval; + } + +} diff --git a/tests/unit/com/raytheon/uf/common/time/domain/UsesTimePoint.java b/tests/unit/com/raytheon/uf/common/time/domain/UsesTimePoint.java new file mode 100644 index 0000000000..1dd572c5da --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/time/domain/UsesTimePoint.java @@ -0,0 +1,75 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.time.domain; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.junit.Ignore; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.time.domain.api.ITimePoint; + +/** + * Uses an {@link ITimePoint}. Used by {@link TimePointTest} to verify Jaxb + * interoperability. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 11, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@Ignore +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class UsesTimePoint { + + @DynamicSerializeElement + @XmlElement + private ITimePoint timePoint; + + /** + * @return the timePoint + */ + public ITimePoint getTimePoint() { + return timePoint; + } + + /** + * @param timePoint + * the timePoint to set + */ + public void setTimePoint(ITimePoint timePoint) { + this.timePoint = timePoint; + } + +} diff --git a/tests/unit/com/raytheon/uf/edex/datadelivery/harvester/CrawlerTest.java b/tests/unit/com/raytheon/uf/edex/datadelivery/harvester/CrawlerTest.java index 71e70de688..0308ecacc6 100644 --- a/tests/unit/com/raytheon/uf/edex/datadelivery/harvester/CrawlerTest.java +++ b/tests/unit/com/raytheon/uf/edex/datadelivery/harvester/CrawlerTest.java @@ -22,6 +22,7 @@ package com.raytheon.uf.edex.datadelivery.harvester; import static org.junit.Assert.assertEquals; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; @@ -30,6 +31,7 @@ import org.junit.Test; import org.mockito.Mockito; import com.raytheon.uf.common.localization.PathManagerFactoryTest; +import com.raytheon.uf.common.time.domain.Durations; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.common.time.util.TimeUtilTest; import com.raytheon.uf.edex.datadelivery.harvester.config.HarvesterConfig; @@ -105,7 +107,8 @@ public class CrawlerTest { TimeUtilTest.freezeTime(time); HarvesterConfig harvesterConfig = HarvesterConfigFixture.INSTANCE.get(); - harvesterConfig.getProvider().setPostedFileDelay("3 DAYS"); + harvesterConfig.getProvider().setPostedFileDelay( + Durations.of(3, TimeUnit.DAYS)); MainSequenceCrawler crawler = new MainSequenceCrawler(harvesterConfig, mockCommunicationStrategy); List modelCrawlConfigs = crawler @@ -129,7 +132,7 @@ public class CrawlerTest { TimeUtilTest.freezeTime(time); HarvesterConfig harvesterConfig = HarvesterConfigFixture.INSTANCE.get(); - harvesterConfig.getProvider().setPostedFileDelay("2 MILLISECONDS"); + harvesterConfig.getProvider().setPostedFileDelay(Durations.of(2, TimeUnit.MILLISECONDS)); MainSequenceCrawler crawler = new MainSequenceCrawler(harvesterConfig, mockCommunicationStrategy); List modelCrawlConfigs = crawler diff --git a/tests/unit/com/raytheon/uf/edex/plugin/nwsauth/FileManagerTest.java b/tests/unit/com/raytheon/uf/edex/plugin/nwsauth/FileManagerTest.java new file mode 100644 index 0000000000..820336d9f7 --- /dev/null +++ b/tests/unit/com/raytheon/uf/edex/plugin/nwsauth/FileManagerTest.java @@ -0,0 +1,156 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.plugin.nwsauth; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import javax.xml.bind.JAXBException; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +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.PathManagerFactoryTest; +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.plugin.nwsauth.xml.NwsRoleData; +import com.raytheon.uf.common.plugin.nwsauth.xml.UserXML; +import com.raytheon.uf.common.serialization.JAXBManager; +import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.time.util.TimeUtilTest; + +/** + * Test {@link FileManager}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 17, 2013 1412       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class FileManagerTest { + private static JAXBManager jaxbManager; + + private final UserXML someUser = new UserXML("someUser"); + + private FileManager manager; + + @BeforeClass + public static void classSetup() throws JAXBException { + jaxbManager = new JAXBManager(NwsRoleData.class); + } + + @Before + public void setUp() { + TimeUtilTest.freezeTime(); + PathManagerFactoryTest.initLocalization(); + manager = new FileManager(); + } + + @After + public void tearDown() { + TimeUtilTest.resumeTime(); + } + + @Test + public void fileNewerOnDiskIsReadBeforeResponse() + throws LocalizationException { + + addUserToUserAdminFile(); + + verifyUserIsFoundWhenRoleDataRetrieved(); + } + + @Test + public void fileOlderOnDiskIsNotReadBeforeResponse() + throws LocalizationException { + + addUserToUserAdminFile(); + setUserAdminFileModifiedTimeToOneSecondAgo(); + + verifyUserIsNotFoundWhenRoleDataRetrieved(); + } + + private void verifyUserIsFoundWhenRoleDataRetrieved() { + final Map roleDataMap = manager.getRoleDataMap(); + assertTrue( + "Did not find the user added to the role data map!", + roleDataMap.get("TestUserRoles").getUserList() + .contains(someUser)); + } + + /** + * @param someUser + */ + private void verifyUserIsNotFoundWhenRoleDataRetrieved() { + final Map roleDataMap = manager.getRoleDataMap(); + assertFalse( + "Should not have found the user added to the role data map!", + roleDataMap.get("TestUserRoles").getUserList() + .contains(someUser)); + + } + + private void addUserToUserAdminFile() throws LocalizationException { + final LocalizationFile file = getTestUserAdminRolesLocalizationFile(); + NwsRoleData roleData = file.jaxbUnmarshal(NwsRoleData.class, + jaxbManager); + + roleData.getUserList().add(someUser); + file.jaxbMarshal(roleData, jaxbManager); + file.save(); + // The file was written out 1 second after we last read it + file.getFile().setLastModified( + TimeUtil.currentTimeMillis() + TimeUtil.MILLIS_PER_SECOND); + } + + private void setUserAdminFileModifiedTimeToOneSecondAgo() { + // The file was written out 1 second before we last read it + getTestUserAdminRolesLocalizationFile().getFile().setLastModified( + TimeUtil.currentTimeMillis() - TimeUtil.MILLIS_PER_SECOND); + } + + private LocalizationFile getTestUserAdminRolesLocalizationFile() { + IPathManager pathManager = PathManagerFactory.getPathManager(); + final LocalizationFile file = pathManager.getLocalizationFile( + new LocalizationContext(LocalizationType.COMMON_STATIC, + LocalizationLevel.SITE, "OAX"), + "roles/testUserAdminRoles.xml"); + return file; + } + +} diff --git a/tests/unit/com/raytheon/uf/edex/stats/AggregateManagerTest.java b/tests/unit/com/raytheon/uf/edex/stats/AggregateManagerTest.java new file mode 100644 index 0000000000..5590fa147e --- /dev/null +++ b/tests/unit/com/raytheon/uf/edex/stats/AggregateManagerTest.java @@ -0,0 +1,116 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.stats; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBException; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.Maps; +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +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.PathManagerFactoryTest; +import com.raytheon.uf.common.serialization.JAXBManager; +import com.raytheon.uf.common.stats.StatsGrouping; +import com.raytheon.uf.common.stats.StatsGroupingColumn; +import com.raytheon.uf.common.stats.xml.StatisticsConfig; +import com.raytheon.uf.common.stats.xml.StatisticsEvent; +import com.raytheon.uf.common.util.FileUtil; +import com.raytheon.uf.edex.stats.util.ConfigLoader; + +/** + * Test {@link AggregateManager}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 15, 2013 1487       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class AggregateManagerTest { + private static JAXBManager jaxbManager; + + @BeforeClass + public static void classSetUp() throws JAXBException { + jaxbManager = new JAXBManager(StatisticsConfig.class, + StatsGroupingColumn.class); + } + + @Before + public void setUp() { + PathManagerFactoryTest.initLocalization(); + } + + @Test + public void testDeterminingGroupForEvent() throws Exception { + IPathManager pm = PathManagerFactory.getPathManager(); + final LocalizationFile lf = pm.getLocalizationFile( + new LocalizationContext(LocalizationType.EDEX_STATIC, + LocalizationLevel.BASE), FileUtil.join("stats", + "mockStats.xml")); + + final StatisticsConfig statisticsConfig = lf.jaxbUnmarshal( + StatisticsConfig.class, jaxbManager); + + ConfigLoader.validate(Maps. newHashMap(), + statisticsConfig); + + MockEvent mockEvent = new MockEvent(); + mockEvent.setPluginName("somePlugin"); + mockEvent.setFileName("someFileName"); + mockEvent.setProcessingTime(1000L); + mockEvent.setProcessingLatency(500L); + + List groupList = new ArrayList(); + groupList.add(new StatsGrouping("pluginName", "somePlugin")); + groupList.add(new StatsGrouping("fileName", "someFileName")); + StatsGroupingColumn column = new StatsGroupingColumn(); + column.setGroup(groupList); + + final String expectedGroupRepresentation = jaxbManager + .marshalToXml(column); + final String actualGroupRepresentation = AggregateManager.determineGroupRepresentationForEvent( + statisticsConfig.getEvents().iterator().next(), mockEvent); + assertThat(actualGroupRepresentation, + is(equalTo(expectedGroupRepresentation))); + } + +} diff --git a/tests/unit/com/raytheon/uf/edex/stats/MockEvent.java b/tests/unit/com/raytheon/uf/edex/stats/MockEvent.java new file mode 100644 index 0000000000..419ed5be0f --- /dev/null +++ b/tests/unit/com/raytheon/uf/edex/stats/MockEvent.java @@ -0,0 +1,169 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.stats; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.stats.ProcessEvent; +import com.raytheon.uf.common.stats.StatisticsEvent; + +/** + * Mock event based from {@link ProcessEvent}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 15, 2013 1487       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@DynamicSerialize +public class MockEvent extends StatisticsEvent { + + private static final long serialVersionUID = 1L; + + private static final Map FIELD_UNIT_MAP; + static { + Map m = new HashMap(); + m.put("processingLatency", "ms"); + m.put("processingTime", "ms"); + FIELD_UNIT_MAP = Collections.unmodifiableMap(m); + } + + @DynamicSerializeElement + private String message; + + @DynamicSerializeElement + private String pluginName; + + @DynamicSerializeElement + private String fileName; + + /* + * Processing time in milliseconds + */ + @DynamicSerializeElement + private long processingTime; + + /* + * Processing latency in milliseconds + */ + @DynamicSerializeElement + private long processingLatency; + + public MockEvent() { + } + + @Override + protected Map getFieldUnitMap() { + return FIELD_UNIT_MAP; + } + + /** + * @return the fileName + */ + public String getFileName() { + return fileName; + } + + /** + * @return the message + */ + public String getMessage() { + return message; + } + + /** + * @return the pluginName + */ + public String getPluginName() { + return pluginName; + } + + /** + * @return the processingLatency in milliseconds + */ + public long getProcessingLatency() { + return processingLatency; + } + + /** + * @return the processingTime in milliseconds + */ + public long getProcessingTime() { + return processingTime; + } + + /** + * @param fileName + * the fileName to set + */ + public void setFileName(String fileName) { + this.fileName = fileName; + } + + /** + * @param message + * the message to set + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @param pluginName + * the pluginName to set + */ + public void setPluginName(String pluginName) { + this.pluginName = pluginName; + } + + /** + * @param processingLatency + * the processingLatency in milliseconds to set + */ + public void setProcessingLatency(long processingLatency) { + this.processingLatency = processingLatency; + } + + /** + * @param processingTime + * the processingTime in milliseconds to set + */ + public void setProcessingTime(long processingTime) { + this.processingTime = processingTime; + } + + @Override + public String toString() { + return super.toString() + " : " + getMessage(); + } + +} \ No newline at end of file diff --git a/tests/unit/com/raytheon/uf/edex/stats/data/StatsDataAccumulatorTest.java b/tests/unit/com/raytheon/uf/edex/stats/data/StatsDataAccumulatorTest.java index 4e6288206e..b07a538238 100644 --- a/tests/unit/com/raytheon/uf/edex/stats/data/StatsDataAccumulatorTest.java +++ b/tests/unit/com/raytheon/uf/edex/stats/data/StatsDataAccumulatorTest.java @@ -1,47 +1,92 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ package com.raytheon.uf.edex.stats.data; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.ArrayList; -import java.util.Calendar; +import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; -import java.util.TimeZone; + +import javax.xml.bind.JAXBException; import org.junit.Test; +import com.google.common.collect.Maps; +import com.raytheon.uf.common.datadelivery.event.retrieval.DataRetrievalEvent; +import com.raytheon.uf.common.datadelivery.event.retrieval.SubscriptionRetrievalEvent; +import com.raytheon.uf.common.serialization.JAXBManager; import com.raytheon.uf.common.stats.AggregateRecord; +import com.raytheon.uf.common.stats.StatsGrouping; +import com.raytheon.uf.common.stats.StatsGroupingColumn; +import com.raytheon.uf.common.stats.data.StatsData; import com.raytheon.uf.common.stats.util.UnitUtils; import com.raytheon.uf.common.time.TimeRange; +import com.raytheon.uf.common.time.util.TimeUtil; +/** + * + * Test {@link StatsDataAccumulator}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 15, 2013 1487       djohnson     Use XML for grouping column.
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ public class StatsDataAccumulatorTest { + private static final JAXBManager JAXB_MANAGER; + static { + try { + JAXB_MANAGER = new JAXBManager(StatsGroupingColumn.class); + } catch (JAXBException e) { + throw new ExceptionInInitializerError(e); + } + } + @Test public void testCalculateBinsCalculatesCorrectly() { - Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - c.set(Calendar.MILLISECOND, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.DAY_OF_MONTH, 1); - c.set(Calendar.MONTH, 0); - long start = c.getTimeInMillis(); - - c.add(Calendar.DAY_OF_MONTH, 1); - long end = c.getTimeInMillis(); - - TimeRange tr = new TimeRange(start, end); + TimeRange tr = new TimeRange(0L, TimeUtil.MILLIS_PER_DAY); StatsDataAccumulator acc = new StatsDataAccumulator(); acc.setTimeRange(tr); acc.setTimeStep(5); acc.calculateBins(); - int expectedBinCount = 288; // 5 minute bins 12 per hour, * 24 + int expectedBinCount = 288; // 5 minute bins 12 per hour, * 24 int actualBinCount = acc.bins.keySet().size(); - assertEquals("Bin Counts do not match", expectedBinCount, actualBinCount); + assertEquals("Bin Counts do not match", expectedBinCount, + actualBinCount); int count = 0; for (long bin : acc.bins.keySet()) { @@ -51,7 +96,7 @@ public class StatsDataAccumulatorTest { } @Test - public void testSetupGroupings() { + public void testSetupGroupings() throws JAXBException { List recordList = getTestRecords(); StatsDataAccumulator acc = new StatsDataAccumulator(); acc.setRecords(recordList.toArray(new AggregateRecord[recordList.size()])); @@ -62,33 +107,39 @@ public class StatsDataAccumulatorTest { expectedGroups.add("provider"); expectedGroups.add("plugin"); - List expectedGroupMembers = new ArrayList(); - expectedGroupMembers.add("nomads"); - expectedGroupMembers.add("madis"); - expectedGroupMembers.add("owner0"); - expectedGroupMembers.add("owner1"); - expectedGroupMembers.add("owner2"); - expectedGroupMembers.add("owner3"); - expectedGroupMembers.add("owner4"); - expectedGroupMembers.add("grid"); + List expectedPlugins = Arrays.asList("grid"); + List expectedProviders = Arrays.asList("nomads", "madis"); + List expectedOwners = Arrays.asList("owner0", "owner1", + "owner2", "owner3", "owner4"); + Map> expectedGroupsToValues = Maps.newHashMap(); + expectedGroupsToValues.put("provider", expectedProviders); + expectedGroupsToValues.put("plugin", expectedPlugins); + expectedGroupsToValues.put("owner", expectedOwners); // Check the groups - for (String group : acc.groups) { - assertTrue(expectedGroups.contains(group)); + for (String expected : expectedGroups) { + assertTrue("Did not find group [" + expected + + "] in the group collection!", + acc.groups.contains(expected)); } // Check the group members - for (String key: acc.groupMemberMap.keySet()) { - for (String member: acc.groupMemberMap.get(key)) { - assertTrue(expectedGroupMembers.contains(member)); + final Map> groupMemberMap = acc.groupMemberMap; + for (Entry> entry : expectedGroupsToValues + .entrySet()) { + final String groupName = entry.getKey(); + final Set setToCheck = groupMemberMap.get(groupName); + for (String member : entry.getValue()) { + assertTrue("Did not find entry [" + member + "] for group [" + + groupName + "]!", setToCheck.contains(member)); } } } @Test - public void testCreateStatsDataMapCreation() { - String eventType = "com.raytheon.uf.common.datadelivery.event.retrieval.DataRetrievalEvent"; + public void testCreateStatsDataMapCreation() throws JAXBException { + String eventType = DataRetrievalEvent.class.getName(); String dataType = "bytes"; String displayUnit = "MB"; @@ -102,7 +153,7 @@ public class StatsDataAccumulatorTest { acc.setDataType(dataType); acc.setupGroupings(); - acc.createStatsDataMap(unitUtils, acc.groups); + acc.createStatsDataMap(acc.groups); Set expectedSet = new HashSet(); expectedSet.add("owner0:nomads"); @@ -116,54 +167,54 @@ public class StatsDataAccumulatorTest { expectedSet.add("owner3:madis"); expectedSet.add("owner4:madis"); - for (String key : acc.statsDataMap.keySet()) { - assertTrue(expectedSet.contains(key)); + final Map statsDataMap = acc.statsDataMap; + for (String expected : expectedSet) { + assertTrue("Did not find expected value (" + expected + + "] as key in the statsDataMap!", + statsDataMap.containsKey(expected)); } } // Build the Aggregate records - private List getTestRecords() { + private List getTestRecords() throws JAXBException { String plugin = "plugin"; String provider = "provider"; String nomads = "nomads"; String madis = "madis"; String owner = "owner"; String grid = "grid"; - String dash = "-"; - String colon = ":"; - List groupings = new ArrayList(); - for (int i = 0; i < 5; i++) { - groupings.add(plugin + colon + grid + dash + owner + colon + owner + i); + List groupingColumns = new ArrayList(); + for (int i = 0; i < 15; i++) { + groupingColumns.add(StatsGroupingColumn.withGroupings( + new StatsGrouping(plugin, grid), new StatsGrouping(owner, + owner + i))); } for (int i = 0; i < 5; i++) { - groupings.add(plugin + colon + grid + dash + owner + colon + owner + i); + groupingColumns.add(StatsGroupingColumn.withGroupings( + new StatsGrouping(provider, nomads), new StatsGrouping( + owner, owner + i))); } for (int i = 0; i < 5; i++) { - groupings.add(plugin + colon + grid + dash + owner + colon + owner + i); - } - - for (int i = 0; i < 5; i++) { - groupings.add(provider + colon + nomads + dash + owner + colon + owner + i); - } - for (int i = 0; i < 5; i++) { - groupings.add(provider + colon + madis + dash + owner + colon + owner + i); + groupingColumns.add(StatsGroupingColumn.withGroupings( + new StatsGrouping(provider, madis), new StatsGrouping( + owner, owner + i))); } List records = new ArrayList(); - for (String group : groupings) { + for (StatsGroupingColumn group : groupingColumns) { AggregateRecord r = new AggregateRecord(); - if (group.contains("provider")) { - r.setEventType("com.raytheon.uf.common.datadelivery.event.retrieval.DataRetrievalEvent"); + if ("provider".equals(group.getGroup().iterator().next().getName())) { + r.setEventType(DataRetrievalEvent.class.getName()); r.setField("bytes"); } else { - r.setEventType("com.raytheon.uf.common.datadelivery.event.retrieval.SubscriptionRetrievalEvent"); + r.setEventType(SubscriptionRetrievalEvent.class.getName()); r.setField("numRecords"); } - r.setGrouping(group); + r.setGrouping(JAXB_MANAGER.marshalToXml(group)); records.add(r); } diff --git a/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/AbstractSubscriptionServiceTest.java b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/AbstractSubscriptionServiceTest.java index ed367b5755..3fbbbd6c89 100644 --- a/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/AbstractSubscriptionServiceTest.java +++ b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/AbstractSubscriptionServiceTest.java @@ -48,6 +48,7 @@ import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture; import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler; +import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.registry.handler.RegistryObjectHandlersUtil; import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService.ISubscriptionServiceResult; diff --git a/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/LatencyRuleXMLTest.java b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/LatencyRuleXMLTest.java new file mode 100644 index 0000000000..2ac91180a3 --- /dev/null +++ b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/LatencyRuleXMLTest.java @@ -0,0 +1,86 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.datadelivery.subscription.xml; + +import javax.xml.bind.JAXBException; + +import org.junit.Test; + +import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture; +import com.raytheon.uf.common.units.DataSizeUnit; +import com.raytheon.uf.common.util.CollectionUtil; +import com.raytheon.uf.viz.datadelivery.system.CreateEditRuleDlg.FreqUnitOptions; +import com.raytheon.uf.viz.datadelivery.system.OperatorTypes; +import com.raytheon.uf.viz.datadelivery.system.OpsNetFieldNames; + +/** + * Test {@link LatencyRulesXML}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * Jan 17, 2013 1357       mpduff       DataSizeUnits was moved.
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class LatencyRuleXMLTest { + + /** + * Rule data size units were being written out as "Byte" but expected to be + * BYTE when running matches. + * + * @throws JAXBException + */ + @Test + public void testDataSizeUnitCanBeUsedInMatches() throws JAXBException { + LatencyRuleXML ruleXml = new LatencyRuleXML(); + ruleXml.setLatency(10); + ruleXml.setRuleField(OpsNetFieldNames.SIZE.toString()); + ruleXml.setRuleName("ruleName"); + ruleXml.setRuleOperator(OperatorTypes.GREATER_THAN); + ruleXml.setRuleUnit(DataSizeUnit.BYTE.getUnit()); + ruleXml.setRuleValue("10"); + + ruleXml.matches(SubscriptionFixture.INSTANCE.get(), + CollectionUtil.asSet(1, 2)); + } + + @Test + public void testFrequencyUnitCanBeUsedInMatches() throws JAXBException { + LatencyRuleXML ruleXml = new LatencyRuleXML(); + ruleXml.setLatency(10); + ruleXml.setRuleField(OpsNetFieldNames.FREQUENCY.toString()); + ruleXml.setRuleName("ruleName"); + ruleXml.setRuleOperator(OperatorTypes.GREATER_THAN); + ruleXml.setRuleUnit(FreqUnitOptions.MIN.getOperation()); + ruleXml.setRuleValue("10"); + + ruleXml.matches(SubscriptionFixture.INSTANCE.get(), + CollectionUtil.asSet(1, 2)); + } +} diff --git a/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/OperatorAdapterTest.java b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/OperatorAdapterTest.java new file mode 100644 index 0000000000..fe4ca85486 --- /dev/null +++ b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/OperatorAdapterTest.java @@ -0,0 +1,75 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.datadelivery.subscription.xml; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import com.raytheon.uf.viz.datadelivery.system.Operator; +import com.raytheon.uf.viz.datadelivery.system.OperatorTypes; +import com.raytheon.uf.viz.datadelivery.utils.NameOperationItems; +import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems; + +/** + * Test {@link OperatorAdapter}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +@SuppressWarnings({ "rawtypes" }) +public class OperatorAdapterTest { + + @Test + public void testMarshalUnmarshalOperatorNameOperationItems() { + verifyOperatorsUnmarshalAsSameOperator(NameOperationItems.values()); + } + + @Test + public void testMarshalUnmarshalOperatorOperatorTypes() { + verifyOperatorsUnmarshalAsSameOperator(OperatorTypes.values()); + } + + @Test + public void testMarshalUnmarshalOperatorTypeOperationItems() { + verifyOperatorsUnmarshalAsSameOperator(TypeOperationItems.values()); + } + + private void verifyOperatorsUnmarshalAsSameOperator(Operator... operators) { + for (Operator operator : operators) { + Operator expected = OperatorAdapter.fromString(OperatorAdapter + .toString(operator)); + assertThat(operator, is(sameInstance(expected))); + } + } + +} diff --git a/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXMLTest.java b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXMLTest.java index 84a566c9c0..d219a1cbe2 100644 --- a/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXMLTest.java +++ b/tests/unit/com/raytheon/uf/viz/datadelivery/subscription/xml/RuleXMLTest.java @@ -30,10 +30,11 @@ import org.junit.Test; import com.raytheon.uf.common.datadelivery.registry.DataType; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.units.DataSizeUnit; import com.raytheon.uf.viz.datadelivery.system.CreateEditRuleDlg.FreqUnitOptions; +import com.raytheon.uf.viz.datadelivery.system.Operator; import com.raytheon.uf.viz.datadelivery.system.OperatorTypes; import com.raytheon.uf.viz.datadelivery.system.OpsNetFieldNames; -import com.raytheon.uf.viz.datadelivery.utils.DataSizeUnit; import com.raytheon.uf.viz.datadelivery.utils.NameOperationItems; import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems; @@ -46,7 +47,9 @@ import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 3, 2013 1420 mpduff Initial creation. + * Jan 03, 2013 1420 mpduff Initial creation. + * Jan 14, 2013 1286 djohnson Use the rule operator as an {@link Operator}. + * Jan 17, 2013 1357 mpduff DataSizeUnits was moved. * * * @@ -70,7 +73,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue("GFS"); rule.setRuleField(OpsNetFieldNames.NAME.getFieldName()); - rule.setRuleOperator(NameOperationItems.LIKE.getOperation()); + rule.setRuleOperator(NameOperationItems.LIKE); assertTrue("Matches Data Set Name failed", rule.matches(sub, null)); } @@ -80,7 +83,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue("GFS2"); rule.setRuleField(OpsNetFieldNames.NAME.getFieldName()); - rule.setRuleOperator(NameOperationItems.LIKE.getOperation()); + rule.setRuleOperator(NameOperationItems.LIKE); assertFalse("Matches Data Set Name false positive", rule.matches(sub, null)); @@ -91,7 +94,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue("GRID,OBS"); rule.setRuleField(OpsNetFieldNames.TYPE.getFieldName()); - rule.setRuleOperator(TypeOperationItems.IN.getOperation()); + rule.setRuleOperator(TypeOperationItems.IN); assertTrue("Matches Data Type In Failed", rule.matches(sub, null)); } @@ -101,7 +104,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue("FAKE"); rule.setRuleField(OpsNetFieldNames.TYPE.getFieldName()); - rule.setRuleOperator(TypeOperationItems.NOT_IN.getOperation()); + rule.setRuleOperator(TypeOperationItems.NOT_IN); assertTrue("Matches Data Type Not In Failed", rule.matches(sub, null)); } @@ -111,7 +114,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue(String.valueOf(100)); rule.setRuleField(OpsNetFieldNames.SIZE.getFieldName()); - rule.setRuleOperator(OperatorTypes.EQUAL.getOperation()); + rule.setRuleOperator(OperatorTypes.EQUAL); rule.setRuleUnit(DataSizeUnit.KB.getUnit()); assertTrue("Matches Dataset Size Equals Failed", @@ -123,7 +126,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue(String.valueOf(100)); rule.setRuleField(OpsNetFieldNames.SIZE.getFieldName()); - rule.setRuleOperator(OperatorTypes.EQUAL.getOperation()); + rule.setRuleOperator(OperatorTypes.EQUAL); rule.setRuleUnit(DataSizeUnit.MB.getUnit()); sub.setDataSetSize(1024 * 100); @@ -136,7 +139,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue(String.valueOf(100)); rule.setRuleField(OpsNetFieldNames.SIZE.getFieldName()); - rule.setRuleOperator(OperatorTypes.EQUAL.getOperation()); + rule.setRuleOperator(OperatorTypes.EQUAL); rule.setRuleUnit(DataSizeUnit.GB.getUnit()); sub.setDataSetSize(100 * 1024 * 1024); @@ -151,7 +154,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue(String.valueOf(60)); rule.setRuleField(OpsNetFieldNames.FREQUENCY.getFieldName()); - rule.setRuleOperator(OperatorTypes.EQUAL.getOperation()); + rule.setRuleOperator(OperatorTypes.EQUAL); rule.setRuleUnit(FreqUnitOptions.MIN.getOperation()); Set cycles = new TreeSet(); @@ -167,7 +170,7 @@ public class RuleXMLTest { LatencyRuleXML rule = new LatencyRuleXML(); rule.setRuleValue(String.valueOf(1)); rule.setRuleField("Dataset Frequency"); - rule.setRuleOperator(OperatorTypes.EQUAL.getOperation()); + rule.setRuleOperator(OperatorTypes.EQUAL); rule.setRuleUnit(FreqUnitOptions.HOURS.getOperation()); Set cycles = new TreeSet(); diff --git a/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtilsTest.java b/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtilsTest.java new file mode 100644 index 0000000000..afb47cae91 --- /dev/null +++ b/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtilsTest.java @@ -0,0 +1,119 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.datadelivery.utils; + +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Sets.newHashSet; +import static org.junit.Assert.assertEquals; + +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; + +import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSet; +import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSetFixture; +import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture; +import com.raytheon.uf.common.datadelivery.registry.Time; + +/** + * Test {@link DataDeliveryUtils}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 14, 2013 1286       djohnson     Initial creation
+ * Jan 22, 2013 1519       djohnson     Add tests for getMaxLatency calculations.
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class DataDeliveryUtilsTest { + + // These constants are not using TimeUtil to make sure we get a + // "second opinion" when using TimeUtil in the code under test + private static final long THREE_HOURS_AS_MINUTES = TimeUnit.HOURS + .toMinutes(3); + + private static final long MINUTES_PER_DAY = TimeUnit.DAYS.toMinutes(1); + + @Test + public void maxLatencyReturnsMaxCyclicDifferenceForSubscribedToCycles() { + List cycleTimes = newArrayList(); + cycleTimes.add(0); + cycleTimes.add(1); + cycleTimes.add(4); + + Subscription subscription = SubscriptionFixture.INSTANCE.get(); + Time subTime = subscription.getTime(); + subTime.setCycleTimes(cycleTimes); + + assertEquals(THREE_HOURS_AS_MINUTES, + DataDeliveryUtils.getMaxLatency(subscription)); + } + + @Test + public void maxLatencyDefaultsToOneDayForSubscriptionWithOneCycle() { + List cycleTimes = newArrayList(); + cycleTimes.add(0); + + Subscription subscription = SubscriptionFixture.INSTANCE.get(); + Time subTime = subscription.getTime(); + subTime.setCycleTimes(cycleTimes); + + assertEquals(MINUTES_PER_DAY, + DataDeliveryUtils.getMaxLatency(subscription)); + } + + @Test + public void maxLatencyForDataSetWithOneCycleDefaultsToOneDay() { + Set cycleTimes = newHashSet(); + cycleTimes.add(0); + + OpenDapGriddedDataSet dataset = OpenDapGriddedDataSetFixture.INSTANCE + .get(); + dataset.setCycles(cycleTimes); + + assertEquals(MINUTES_PER_DAY, DataDeliveryUtils.getMaxLatency(dataset)); + } + + @Test + public void maxLatencyForDataSetWithMultipleCyclesReturnsMaxCyclicDifference() { + Set cycleTimes = newHashSet(); + cycleTimes.add(0); + cycleTimes.add(1); + cycleTimes.add(4); + + OpenDapGriddedDataSet dataset = OpenDapGriddedDataSetFixture.INSTANCE + .get(); + dataset.setCycles(cycleTimes); + + assertEquals(THREE_HOURS_AS_MINUTES, + DataDeliveryUtils.getMaxLatency(dataset)); + } + +} diff --git a/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataSizeUtilTest.java b/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataSizeUtilTest.java index f246a52532..134298cb9d 100644 --- a/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataSizeUtilTest.java +++ b/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataSizeUtilTest.java @@ -25,6 +25,8 @@ import static org.junit.Assert.assertThat; import org.junit.Test; +import com.raytheon.uf.common.units.DataSizeUnit; + /** * Test {@link DataSizeUnit} * @@ -34,7 +36,8 @@ import org.junit.Test; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 8, 2013 1420 mpduff Initial creation + * Jan 08, 2013 1420 mpduff Initial creation + * Jan 17, 2013 1357 mpduff DataSizeUnits was moved. * * * diff --git a/tests/unit/com/raytheon/uf/viz/stats/ui/SelectionEntryTest.java b/tests/unit/com/raytheon/uf/viz/stats/ui/SelectionEntryTest.java new file mode 100644 index 0000000000..d728231f3e --- /dev/null +++ b/tests/unit/com/raytheon/uf/viz/stats/ui/SelectionEntryTest.java @@ -0,0 +1,54 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.stats.ui; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * SelectionEntry test class. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 24, 2013            mpduff     Initial creation
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +public class SelectionEntryTest { + + @Test + public void testCreateSelectionEntryClassAndAddKeys() { + SelectionEntry se = new SelectionEntry(); + se.addPair("Key", "Value"); + se.addPair("Key2", "Value2"); + se.addPair("Key3", "Value3"); + assertTrue("Keys are wrong", se.toString() + .equals("Value:Value2:Value3")); + } +} diff --git a/tests/utility/common_static/site/OAX/roles/testUserAdminRoles.xml b/tests/utility/common_static/site/OAX/roles/testUserAdminRoles.xml new file mode 100644 index 0000000000..5e02c0ca3d --- /dev/null +++ b/tests/utility/common_static/site/OAX/roles/testUserAdminRoles.xml @@ -0,0 +1,14 @@ + + + + TestUserRoles + + + This permission allows the user to access and edit AWIPS 2 User Administration + + + + + awips.user.admin + + \ No newline at end of file diff --git a/tests/utility/edex_static/base/stats/mockStats.xml b/tests/utility/edex_static/base/stats/mockStats.xml new file mode 100644 index 0000000000..3c9c5aef7a --- /dev/null +++ b/tests/utility/edex_static/base/stats/mockStats.xml @@ -0,0 +1,12 @@ + + + + + + + + +