From f0d1c1a737bdc227165b375d40d56b7202dc8e56 Mon Sep 17 00:00:00 2001 From: Ben Steffensmeier Date: Thu, 17 Jan 2013 10:15:43 -0600 Subject: [PATCH] Issue #1495 add ensemble selection tab to subset dialog Change-Id: I71c599428285c9d394529a77359a4ba61dd88f15 Former-commit-id: e884c8e79f05af8fb3252fa7a492d232ba090715 --- .../subset/GriddedEnsembleSubsetTab.java | 177 +++++++++++++++++ .../subset/GriddedSubsetManagerDlg.java | 98 +++++++++- .../subscription/subset/SubsetManagerDlg.java | 185 +++++++----------- .../subset/VerticalSubsetTab.java | 2 +- .../subscription/subset/xml/SubsetXML.java | 19 ++ .../harvester/NOMADS-harvester.xml | 6 +- .../opendap/OpenDAPRetrievalGenerator.java | 7 - 7 files changed, 371 insertions(+), 123 deletions(-) create mode 100644 cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/GriddedEnsembleSubsetTab.java 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 442698ad35..a72b5fb083 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,7 @@ 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. * * * @@ -115,6 +122,8 @@ public class GriddedSubsetManagerDlg private DataSetMetaData metaData; + private GriddedEnsembleSubsetTab ensembleTab; + /** * Constructor. * @@ -150,6 +159,82 @@ 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); + } + } + + /* + * (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} */ @@ -187,7 +272,9 @@ public class GriddedSubsetManagerDlg time.setSelectedTimeIndices(fcstIndices); subscription.setTime(time); - subscription.setEnsemble(dataSet.getEnsemble()); + if (ensembleTab != null) { + ensembleTab.populateSubscription(subscription); + } return subscription; } @@ -196,7 +283,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(); @@ -273,7 +360,12 @@ public class GriddedSubsetManagerDlg // Get the temporal data int numFcstHours = this.timingTabControls.getSelectedFcstHours().length; dataSize.setNumFcstHours(numFcstHours); - dataSize.setNumEnsembleMembers(dataSet.getEnsemble()); + 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/SubsetManagerDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/SubsetManagerDlg.java index e9c6a9e22f..85952557af 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,6 +20,7 @@ package com.raytheon.uf.viz.datadelivery.subscription.subset; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -137,9 +138,6 @@ public abstract class SubsetManagerDlg tabTextMap = new HashMap(); - /** Subset Name text box */ private Text nameText; @@ -180,15 +178,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 +794,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 +818,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 +880,8 @@ public abstract class SubsetManagerDlg levelMap = new HashMap(); @@ -946,9 +916,9 @@ public abstract class SubsetManagerDlg vertList = new ArrayList( + levelMap.values()); + vTab.populate(vertList, dataSet); } /** @@ -956,25 +926,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/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/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..ce81454ac9 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 @@ -45,9 +45,9 @@ \.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.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 9ae6f3f8eb..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 @@ -288,13 +288,6 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator { List retrievals = new ArrayList(); Subscription sub = bundle.getSubscription(); - if (sub.getEnsemble() != null && !sub.getEnsemble().hasSelection()) { - // TODO remove this once the UI allows you to make an ensemble - // selection. - sub.getEnsemble() - .setSelectedMembers(sub.getEnsemble().getMembers()); - } - int sfactor = getSizingFactor(getDimensionalSize(sub.getCoverage())); sub = removeDuplicates(sub);