Issue #2386 - Implement the front end for multiple data type overlap rules

Peer review comments

Change-Id: I1f0186b3e08f3013a6dc4dc3dbf7c2e0a19404bf

Former-commit-id: 10f3fa86b0 [formerly c4e501aaf9] [formerly a220ff05b0] [formerly 10f3fa86b0 [formerly c4e501aaf9] [formerly a220ff05b0] [formerly a69120c623 [formerly a220ff05b0 [formerly 69a5242579fdeacceba5ed2ce73be01e671328ae]]]]
Former-commit-id: a69120c623
Former-commit-id: 27fd5ba0fa [formerly 610c937a00] [formerly 5c24818dd9e96881368fc526e9d32dce344061c7 [formerly f9074dc896]]
Former-commit-id: d7fa01a403613e0c322898b648e1b5619df67008 [formerly eaa8e67afd]
Former-commit-id: bcabea1df2
This commit is contained in:
Mike Duff 2013-10-11 18:15:03 -05:00
parent 991f4cf832
commit 07da86f077
12 changed files with 1077 additions and 267 deletions

View file

@ -0,0 +1,211 @@
/**
* 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.system;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
/**
* Composite holding the common data type attributes.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 30, 2013 2386 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class CommonAttributeComposite extends Composite {
/** Parameter spinner */
private Spinner parameterSpinner;
/** Spatial spinner */
private Spinner spatialSpinner;
/** ChangeApplpier callback */
private final IChangeApplier callback;
/** Apply all check box */
private Button applyAllBtn;
/**
* Constructor.
*
* @param parent
* Parent Composite
* @param style
* Style bits
* @param callback
* The change apply callback
*/
public CommonAttributeComposite(Composite parent, int style,
IChangeApplier callback) {
super(parent, style);
this.callback = callback;
init();
}
/**
* Initialize class.
*/
private void init() {
GridLayout gl = new GridLayout(1, true);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
this.setLayout(gl);
this.setLayoutData(gd);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gl = new GridLayout(3, false);
Group commonGrp = new Group(this, SWT.NONE);
commonGrp.setLayout(gl);
commonGrp.setLayoutData(gd);
commonGrp.setText(" Common Attributes ");
// Label for directions
gd = new GridData(SWT.FILL, SWT.DEFAULT, false, false);
gd.horizontalSpan = 3;
Label directionsLabel = new Label(commonGrp, SWT.NONE);
directionsLabel.setLayoutData(gd);
directionsLabel
.setText("These attributes are common to all data types.");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
gl = new GridLayout(2, false);
gl.marginRight = 10;
Composite paramComp = new Composite(commonGrp, SWT.NONE);
paramComp.setLayout(gl);
paramComp.setLayoutData(gd);
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT);
Label label = new Label(paramComp, SWT.NONE);
label.setLayoutData(gd);
label.setText("Parameters:");
parameterSpinner = new Spinner(paramComp, SWT.BORDER);
parameterSpinner.setMinimum(0);
parameterSpinner.setMaximum(100);
parameterSpinner.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
callback.applyChange();
}
});
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
gl = new GridLayout(2, false);
gl.marginRight = 10;
Composite spatialComp = new Composite(commonGrp, SWT.NONE);
spatialComp.setLayout(gl);
spatialComp.setLayoutData(gd);
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT);
Label label2 = new Label(spatialComp, SWT.NONE);
label2.setLayoutData(gd);
label2.setText("Spatial:");
spatialSpinner = new Spinner(spatialComp, SWT.BORDER);
spatialSpinner.setMinimum(0);
spatialSpinner.setMaximum(100);
spatialSpinner.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
callback.applyChange();
}
});
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gl = new GridLayout(1, false);
Composite applyAllComp = new Composite(commonGrp, SWT.NONE);
applyAllComp.setLayout(gl);
applyAllComp.setLayoutData(gd);
applyAllBtn = new Button(applyAllComp, SWT.CHECK);
applyAllBtn.setText("Apply to all data types");
applyAllBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
callback.applyChange();
}
});
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
gl = new GridLayout(2, false);
gl.marginRight = 10;
Composite matchComp = new Composite(commonGrp, SWT.NONE);
matchComp.setLayout(gl);
matchComp.setLayoutData(gd);
gd = new GridData(100, SWT.DEFAULT);
Label matchLabel = new Label(matchComp, SWT.NONE);
matchLabel.setLayoutData(gd);
matchLabel.setText("Match:");
}
/**
* @param maxAllowedParameterDuplication
*/
public void setParameterValue(int maxAllowedParameterDuplication) {
this.parameterSpinner.setSelection(maxAllowedParameterDuplication);
}
/**
* @param maxAllowedSpatialDuplication
*/
public void setSpatialValue(int maxAllowedSpatialDuplication) {
this.spatialSpinner.setSelection(maxAllowedSpatialDuplication);
}
/**
* @return
*/
public int getParameterValue() {
return this.parameterSpinner.getSelection();
}
/**
* @return
*/
public int getSpatialValue() {
return this.spatialSpinner.getSelection();
}
/**
* @return
*/
public boolean isApplyAll() {
return applyAllBtn.getSelection();
}
}

View file

@ -0,0 +1,170 @@
/**
* 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.system;
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.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
import com.raytheon.uf.common.datadelivery.registry.DataType;
import com.raytheon.uf.common.datadelivery.service.subscription.GridSubscriptionOverlapConfig;
import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy;
import com.raytheon.uf.common.localization.exception.LocalizationException;
/**
* Gridded subscription overlap rules composite.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 1, 2013 2386 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class GridSubscriptionRuleComposite extends SubscriptionComposite {
/** Forecast hour spinner */
private Spinner fcstHrSpinner;
/** Cycles spinner */
private Spinner cycleSpinner;
/**
* Constructor.
*
* @param parent
* Parent Composite
*/
public GridSubscriptionRuleComposite(Composite parent) {
super(parent, DataType.GRID);
}
/**
* {@inheritDoc}
*/
@Override
protected void initTypeSpecific(Group grp) {
grp.setText(" Gridded Attributes ");
GridLayout gl = new GridLayout(2, false);
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Composite comp = new Composite(grp, SWT.NONE);
comp.setLayout(gl);
comp.setLayoutData(gd);
gl = new GridLayout(2, false);
gl.marginRight = 10;
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
Composite fcstComp = new Composite(comp, SWT.NONE);
fcstComp.setLayout(gl);
fcstComp.setLayoutData(gd);
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT);
Label fcstLbl = new Label(fcstComp, SWT.NONE);
fcstLbl.setText("Forecast Hours:");
fcstLbl.setLayoutData(gd);
fcstHrSpinner = new Spinner(fcstComp, SWT.BORDER);
fcstHrSpinner.setMinimum(0);
fcstHrSpinner.setMaximum(100);
fcstHrSpinner.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setButtonsEnabled();
}
});
gl = new GridLayout(2, false);
gl.marginRight = 10;
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
Composite cycleComp = new Composite(comp, SWT.NONE);
cycleComp.setLayout(gl);
cycleComp.setLayoutData(gd);
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT);
Label cycleLbl = new Label(cycleComp, SWT.NONE);
cycleLbl.setText("Cycles:");
cycleLbl.setLayoutData(gd);
cycleSpinner = new Spinner(cycleComp, SWT.BORDER);
cycleSpinner.setMinimum(0);
cycleSpinner.setMaximum(100);
cycleSpinner.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setButtonsEnabled();
}
});
}
/**
* {@inheritDoc}
*/
@Override
protected final void loadConfiguration() {
super.loadConfiguration();
GridSubscriptionOverlapConfig config = (GridSubscriptionOverlapConfig) ruleManager
.getSubscriptionOverlapRules(DATA_TYPE);
if (config != null) {
this.cycleSpinner.setSelection(config
.getMaxAllowedCycleDuplication());
this.fcstHrSpinner.setSelection(config
.getMaxAllowedForecastHourDuplication());
}
}
/**
* {@inheritDoc}
*/
@Override
boolean saveConfiguration() throws LocalizationException {
GridSubscriptionOverlapConfig config = (GridSubscriptionOverlapConfig) ruleManager
.getSubscriptionOverlapRules(DATA_TYPE);
config.setMaxAllowedParameterDuplication(commonComp.getParameterValue());
config.setMaxAllowedSpatialDuplication(commonComp.getSpatialValue());
config.setMaxAllowedCycleDuplication(this.cycleSpinner.getSelection());
config.setMaxAllowedForecastHourDuplication(this.fcstHrSpinner
.getSelection());
config.setMatchStrategy((SubscriptionOverlapMatchStrategy) matchStrategyCombo
.getData(matchStrategyCombo.getText()));
boolean applyAll = commonComp.isApplyAll();
if (applyAll) {
if (ruleManager.saveOverlapRule(config, DATA_TYPE)) {
return super.applyAll(DATA_TYPE);
} else {
return false;
}
}
return ruleManager.saveOverlapRule(config, DATA_TYPE);
}
}

View file

@ -0,0 +1,45 @@
/**
* 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.system;
/**
* An apply change interface.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 2, 2013 2386 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public interface IChangeApplier {
/**
* Call the applyChange method.
*/
void applyChange();
}

View file

@ -0,0 +1,139 @@
/**
* 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.system;
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.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
import com.raytheon.uf.common.datadelivery.registry.DataType;
import com.raytheon.uf.common.datadelivery.service.subscription.PointSubscriptionOverlapConfig;
import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy;
import com.raytheon.uf.common.localization.exception.LocalizationException;
/**
* Point subscription overlap rules composite.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 1, 2013 2386 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class PointSubscriptionRuleComposite extends SubscriptionComposite {
/** Time spinner */
private Spinner timeSpinner;
/**
* Constructor.
*
* @param parent
* Parent Composite
*/
public PointSubscriptionRuleComposite(Composite parent) {
super(parent, DataType.POINT);
}
/**
* {@inheritDoc}
*/
@Override
protected void initTypeSpecific(Group grp) {
grp.setText(" Point Attributes ");
GridLayout gl = new GridLayout(1, false);
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Composite comp = new Composite(grp, SWT.NONE);
comp.setLayout(gl);
comp.setLayoutData(gd);
gl = new GridLayout(2, false);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Composite attrComp = new Composite(comp, SWT.NONE);
attrComp.setLayout(gl);
attrComp.setLayoutData(gd);
Label label = new Label(attrComp, SWT.NONE);
label.setText("Time:");
timeSpinner = new Spinner(attrComp, SWT.BORDER);
timeSpinner.setMinimum(0);
timeSpinner.setMaximum(100);
timeSpinner.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setButtonsEnabled();
}
});
}
/**
* {@inheritDoc}
*/
@Override
protected final void loadConfiguration() {
super.loadConfiguration();
PointSubscriptionOverlapConfig config = (PointSubscriptionOverlapConfig) ruleManager
.getSubscriptionOverlapRules(DATA_TYPE);
if (config != null) {
timeSpinner.setSelection(config.getMaxAllowedTimeDuplication());
}
}
/**
* {@inheritDoc}
*/
@Override
boolean saveConfiguration() throws LocalizationException {
PointSubscriptionOverlapConfig config = (PointSubscriptionOverlapConfig) ruleManager
.getSubscriptionOverlapRules(DATA_TYPE);
config.setMatchStrategy((SubscriptionOverlapMatchStrategy) matchStrategyCombo
.getData(matchStrategyCombo.getText()));
config.setMaxAllowedParameterDuplication(this.commonComp
.getParameterValue());
config.setMaxAllowedSpatialDuplication(commonComp.getSpatialValue());
config.setMaxAllowedTimeDuplication(timeSpinner.getSelection());
boolean applyAll = commonComp.isApplyAll();
if (applyAll) {
if (ruleManager.saveOverlapRule(config, DATA_TYPE)) {
return super.applyAll(DATA_TYPE);
} else {
return false;
}
}
return ruleManager.saveOverlapRule(config, DATA_TYPE);
}
}

View file

@ -19,31 +19,22 @@
**/ **/
package com.raytheon.uf.viz.datadelivery.system; package com.raytheon.uf.viz.datadelivery.system;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.swt.SWT; 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.GridData;
import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Spinner;
import com.raytheon.uf.common.datadelivery.registry.DataType; import com.raytheon.uf.common.datadelivery.registry.DataType;
import com.raytheon.uf.common.datadelivery.service.subscription.GridSubscriptionOverlapConfig;
import com.raytheon.uf.common.datadelivery.service.subscription.ISubscriptionOverlapService;
import com.raytheon.uf.common.datadelivery.service.subscription.PointSubscriptionOverlapConfig;
import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapConfig; import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapConfig;
import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy; import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy;
import com.raytheon.uf.common.localization.exception.LocalizationException; import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.datadelivery.services.DataDeliveryServices;
import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils;
import com.raytheon.viz.ui.widgets.ApplyCancelComposite; import com.raytheon.viz.ui.widgets.ApplyCancelComposite;
import com.raytheon.viz.ui.widgets.IApplyCancelAction; import com.raytheon.viz.ui.widgets.IApplyCancelAction;
@ -58,6 +49,7 @@ import com.raytheon.viz.ui.widgets.IApplyCancelAction;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Aug 07, 2013 2180 mpduff Initial creation. * Aug 07, 2013 2180 mpduff Initial creation.
* Sept 24, 2013 2386 dhladky Started work on Multiple Type Configs * Sept 24, 2013 2386 dhladky Started work on Multiple Type Configs
* Oct 03, 2013 2386 mpduff Implemented multiple type configs
* *
* </pre> * </pre>
* *
@ -65,243 +57,124 @@ import com.raytheon.viz.ui.widgets.IApplyCancelAction;
* @version 1.0 * @version 1.0
*/ */
public class SubscriptionComposite extends Composite implements public abstract class SubscriptionComposite extends Composite implements
IApplyCancelAction { IApplyCancelAction, IChangeApplier {
/**
* Overlap Spinners enum.
*/
private static enum OverlapSpinners {
PARAMETERS("Parameters:") {
@Override
public int getValue(SubscriptionOverlapConfig config) {
return config.getMaxAllowedParameterDuplication();
}
@Override
public void setValue(SubscriptionOverlapConfig config, int value) {
config.setMaxAllowedParameterDuplication(value);
}
},
FORECAST_HOURS("Forecast Hours:") {
@Override
// TODO: hard coded to Grid for now
public int getValue(SubscriptionOverlapConfig config) {
return ((GridSubscriptionOverlapConfig)config).getMaxAllowedForecastHourDuplication();
}
@Override
public void setValue(SubscriptionOverlapConfig config, int value) {
((GridSubscriptionOverlapConfig)config).setMaxAllowedForecastHourDuplication(value);
}
},
CYCLES("Cycles:") {
@Override
// TODO: hard coded to Grid for now
public int getValue(SubscriptionOverlapConfig config) {
return ((GridSubscriptionOverlapConfig)config).getMaxAllowedCycleDuplication();
}
@Override
public void setValue(SubscriptionOverlapConfig config, int value) {
((GridSubscriptionOverlapConfig)config).setMaxAllowedCycleDuplication(value);
}
},
SPATIAL("Spatial:") {
@Override
public int getValue(SubscriptionOverlapConfig config) {
return config.getMaxAllowedSpatialDuplication();
}
@Override
public void setValue(SubscriptionOverlapConfig config, int value) {
config.setMaxAllowedSpatialDuplication(value);
}
};
private String labelText;
private OverlapSpinners(String labelText) {
this.labelText = labelText;
}
/**
* Get the value from the configuration for this spinner.
*
* @param config
* the config
* @return the value
*/
public abstract int getValue(SubscriptionOverlapConfig config);
/**
* Set the configuration value from the spinner.
*
* @param config
* the configuration
* @param value
* the value
*/
public abstract void setValue(SubscriptionOverlapConfig config,
int value);
}
/** Status Handler */ /** Status Handler */
private final IUFStatusHandler statusHandler = UFStatus private final IUFStatusHandler statusHandler = UFStatus
.getHandler(SubscriptionComposite.class); .getHandler(SubscriptionComposite.class);
/** Subscription overlap service */ /** Rules file manager */
private final ISubscriptionOverlapService overlapService = DataDeliveryServices protected final SystemRuleManager ruleManager = SystemRuleManager
.getSubscriptionOverlapService(); .getInstance();
/** The data type */
protected final DataType DATA_TYPE;
/** Match strategy combo. */ /** Match strategy combo. */
private Combo matchStrategyCombo; protected Combo matchStrategyCombo;
/** Associates the enum spinner configuration to its spinner */
private final EnumMap<OverlapSpinners, Spinner> spinnerMap = new EnumMap<SubscriptionComposite.OverlapSpinners, Spinner>(
OverlapSpinners.class);
/** The listener that should be used to signify changes were made **/
private final Runnable changesWereMade = new Runnable() {
@Override
public void run() {
buttonComp.enableButtons(true);
}
};
/** Button composite */ /** Button composite */
private ApplyCancelComposite buttonComp; protected ApplyCancelComposite buttonComp;
/** Common rule attribute composite */
protected CommonAttributeComposite commonComp;
/** /**
* Constructor. * Constructor.
* *
* @param parent * @param parent
* Parent Composite * Parent Composite
* @param style * @param dataType
* Style bits * Data type represented on this composite
*/ */
public SubscriptionComposite(Composite parent, int style) { public SubscriptionComposite(Composite parent, DataType dataType) {
super(parent, style); super(parent, SWT.NONE);
this.DATA_TYPE = dataType;
init(); init();
} }
/** /**
* Initialize class. * Initialize class.
*/ */
private void init() { protected void init() {
GridLayout gl = new GridLayout(1, true); GridLayout gl = new GridLayout(1, true);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
this.setLayout(gl); this.setLayout(gl);
this.setLayoutData(gd); this.setLayoutData(gd);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gl = new GridLayout(1, false); gl = new GridLayout(1, false);
Composite configurationComposite = new Composite(this, SWT.NONE); Composite configurationComposite = new Composite(this, SWT.NONE);
configurationComposite.setLayout(gl); configurationComposite.setLayout(gl);
configurationComposite.setLayoutData(gd);
// Label for directions gl = new GridLayout(1, false);
gd = new GridData(SWT.FILL, SWT.DEFAULT, false, false);
Label directionsLabel = new Label(configurationComposite, SWT.NONE);
directionsLabel.setLayoutData(gd);
directionsLabel
.setText("Please select a percentage of common items between two "
+ "\nsubscriptions that would cause the subscriptions to be "
+ "\nconsidered overlapping.\n");
gl = new GridLayout(2, false);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gl.marginHeight = 0;
gl.marginWidth = 0;
Composite outerComp = new Composite(configurationComposite, SWT.NONE); commonComp = new CommonAttributeComposite(configurationComposite,
outerComp.setLayoutData(gd); SWT.NONE, this);
outerComp.setLayout(gl); commonComp.setLayout(gl);
commonComp.setLayoutData(gd);
for (final OverlapSpinners overlapSpinner : OverlapSpinners.values()) { gl = new GridLayout(1, false);
gl = new GridLayout(2, false);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Group grp = new Group(configurationComposite, SWT.NONE);
grp.setLayout(gl);
grp.setLayoutData(gd);
Composite spinnerComp = new Composite(outerComp, SWT.NONE); initTypeSpecific(grp);
spinnerComp.setLayoutData(gd);
spinnerComp.setLayout(gl);
gd = new GridData(100, SWT.DEFAULT);
Label label = new Label(spinnerComp, SWT.NONE);
label.setLayoutData(gd);
label.setText(overlapSpinner.labelText);
gd = new GridData(100, SWT.DEFAULT);
final Spinner spinner = new Spinner(spinnerComp, SWT.BORDER);
spinner.setMinimum(0);
spinner.setMaximum(100);
spinnerMap.put(overlapSpinner, spinner);
}
Composite matchStrategyComposite = new Composite(outerComp, SWT.NONE);
gl = new GridLayout(2, false);
matchStrategyComposite.setLayout(gl);
gd = new GridData(100, SWT.DEFAULT);
Label label = new Label(matchStrategyComposite, SWT.NONE);
label.setLayoutData(gd);
label.setText("Match:");
// Match Strategy // Match Strategy
matchStrategyCombo = new Combo(matchStrategyComposite, SWT.READ_ONLY); matchStrategyCombo = new Combo(this, SWT.READ_ONLY);
matchStrategyCombo matchStrategyCombo
.setToolTipText("Select the manner in which the rules should consider two subscriptions to overlap"); .setToolTipText("Select the manner in which the rules should consider two subscriptions to overlap");
matchStrategyCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
applyChange();
}
});
for (SubscriptionOverlapMatchStrategy matchStrategy : SubscriptionOverlapMatchStrategy for (SubscriptionOverlapMatchStrategy matchStrategy : SubscriptionOverlapMatchStrategy
.values()) { .values()) {
matchStrategyCombo.add(matchStrategy.getDisplayString()); matchStrategyCombo.add(matchStrategy.getDisplayString());
matchStrategyCombo.setData(matchStrategy.getDisplayString(),
matchStrategy);
} }
matchStrategyCombo.select(0);
// Buttons // Buttons
buttonComp = new ApplyCancelComposite(this, SWT.NONE, this); buttonComp = new ApplyCancelComposite(this, SWT.NONE, this);
loadConfiguration(); loadConfiguration();
} }
/**
* Initialize the type specific attributes.
*
* @param The
* parent group
*/
abstract void initTypeSpecific(Group grp);
/** /**
* Load configuration data * Load configuration data
*/ */
private void loadConfiguration() { protected void loadConfiguration() {
Map<DataType, SubscriptionOverlapConfig> config = new HashMap<DataType, SubscriptionOverlapConfig>(); SubscriptionOverlapConfig config = ruleManager
try { .getSubscriptionOverlapRules(DATA_TYPE);
config = overlapService.readConfig(); if (config != null) {
} catch (LocalizationException e) { commonComp.setParameterValue(config
statusHandler .getMaxAllowedParameterDuplication());
.handle(Priority.ERROR, commonComp
"Unable to load the subscription overlap rules. " .setSpatialValue(config.getMaxAllowedSpatialDuplication());
+ "Defaulting to configuration that will never overlap.",
e);
config.put(DataType.GRID, new GridSubscriptionOverlapConfig().getNeverOverlaps()); final int indexOfConfigValue = matchStrategyCombo.indexOf(config
config.put(DataType.POINT, new PointSubscriptionOverlapConfig().getNeverOverlaps());
}
// TODO: hard coded to Grid for now
for (Entry<OverlapSpinners, Spinner> entry : spinnerMap.entrySet()) {
final Spinner spinner = entry.getValue();
// Hard coded to Grid until we change front end design
final int initialValue = entry.getKey().getValue(config.get(DataType.GRID));
DataDeliveryGUIUtils.removeListeners(spinner, SWT.Selection,
SWT.DefaultSelection);
spinner.setSelection(initialValue);
spinner.addSelectionListener(DataDeliveryGUIUtils
.addValueChangedSelectionListener(initialValue, spinner,
changesWereMade));
}
DataDeliveryGUIUtils.removeListeners(matchStrategyCombo, SWT.Selection,
SWT.DefaultSelection);
// TODO: hard coded to Grid for now
final int indexOfConfigValue = matchStrategyCombo.indexOf(config.get(DataType.GRID)
.getMatchStrategy().getDisplayString()); .getMatchStrategy().getDisplayString());
matchStrategyCombo.select(indexOfConfigValue); matchStrategyCombo.select(indexOfConfigValue);
matchStrategyCombo.addSelectionListener(DataDeliveryGUIUtils }
.addValueChangedSelectionListener(indexOfConfigValue,
matchStrategyCombo, changesWereMade));
} }
/** /**
@ -310,22 +183,7 @@ public class SubscriptionComposite extends Composite implements
* @return true if saved * @return true if saved
* @throws LocalizationException * @throws LocalizationException
*/ */
private boolean saveConfiguration() throws LocalizationException { abstract boolean saveConfiguration() throws LocalizationException;
// TODO: hard coded to Grid for now
GridSubscriptionOverlapConfig config = new GridSubscriptionOverlapConfig();
for (Entry<OverlapSpinners, Spinner> entry : spinnerMap.entrySet()) {
final OverlapSpinners key = entry.getKey();
key.setValue(config, entry.getValue().getSelection());
}
config.setMatchStrategy(SubscriptionOverlapMatchStrategy.values()[matchStrategyCombo
.getSelectionIndex()]);
overlapService.writeConfig(config);
return true;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -348,5 +206,52 @@ public class SubscriptionComposite extends Composite implements
@Override @Override
public void cancel() { public void cancel() {
loadConfiguration(); loadConfiguration();
buttonComp.enableButtons(false);
}
protected void setButtonsEnabled() {
buttonComp.enableButtons(true);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.datadelivery.system.IChangeApplier#applyChange()
*/
@Override
public void applyChange() {
setButtonsEnabled();
}
/**
* Apply all common attributes.
*
* @param dataType
* The current data type
*
* @return true if saved correctly
*/
protected boolean applyAll(DataType dataType) {
SubscriptionOverlapConfig commonConfig = ruleManager
.getSubscriptionOverlapRules(dataType);
for (DataType dt : DataType.values()) {
if (dt == DataType.PDA) {
// TODO implement PDA
continue;
}
if (dt != dataType) {
SubscriptionOverlapConfig config = ruleManager
.getSubscriptionOverlapRules(dt);
config.setMaxAllowedParameterDuplication(commonConfig
.getMaxAllowedParameterDuplication());
config.setMaxAllowedSpatialDuplication(commonConfig
.getMaxAllowedSpatialDuplication());
if (!ruleManager.saveOverlapRule(config, dt)) {
return false;
}
}
}
return true;
} }
} }

View file

@ -0,0 +1,80 @@
/**
* 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.system;
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.Label;
/**
* Overlap rules composite explaining the overlap rules.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 30, 2013 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class SubscriptionRuleDefinitionComposite extends Composite {
/**
* Constructor.
*
* @param parent
* The parent
*/
public SubscriptionRuleDefinitionComposite(Composite parent) {
super(parent, SWT.NONE);
init();
}
/**
* Initialize the components
*/
private void init() {
GridLayout gl = new GridLayout(1, true);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
this.setLayout(gl);
this.setLayoutData(gd);
Label directionsLabel = new Label(this, SWT.NONE);
directionsLabel.setLayoutData(gd);
StringBuilder buffer = new StringBuilder();
buffer.append("Please select a percentage of items between two subscriptions\n");
buffer.append("that would cause the subscriptions to be considered overlapping.\n");
buffer.append("\nThe common items are items applicable to every data type. These can\n");
buffer.append("changed once for all files or individually depending on the settings.\n");
buffer.append("\nSelect the rule type to edit by expanding the Subscription Rules item");
directionsLabel.setText(buffer.toString());
}
}

View file

@ -62,6 +62,7 @@ import com.raytheon.viz.ui.presenter.IDisplay;
* May 17, 2013 2000 djohnson Move bandwidth configuration into its own tab, add subscription overlap rules. * May 17, 2013 2000 djohnson Move bandwidth configuration into its own tab, add subscription overlap rules.
* Jul 16, 2013 1655 mpduff Add system status tab. * Jul 16, 2013 1655 mpduff Add system status tab.
* Aug 08, 2013 2180 mpduff Redesigned UI. * Aug 08, 2013 2180 mpduff Redesigned UI.
* Oct 03, 2013 2386 mpduff Implemented multiple data types for overlap rules
* *
* </pre> * </pre>
* *
@ -73,7 +74,9 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
private enum SystemManagementSettings { private enum SystemManagementSettings {
PRIORITY_RULES("Priority Rules"), LATENCY_RULES("Latency Rules"), SUBSCRIPTION_RULES( PRIORITY_RULES("Priority Rules"), LATENCY_RULES("Latency Rules"), SUBSCRIPTION_RULES(
"Subscription Rules"), BANDWIDTH("Bandwidth"), DATA_PROVIDER_PASSWORD( "Subscription Rules"), GRID_SUBSCRIPTION_RULES(
"Grid Subscription Rules"), POINT_SUBSCRIPTION_RULES(
"Point Subscription Rules"), BANDWIDTH("Bandwidth"), DATA_PROVIDER_PASSWORD(
"Data Provider Password"), REGISTRY_PROVIDER_STATUS( "Data Provider Password"), REGISTRY_PROVIDER_STATUS(
"Registry/Provider Status"); "Registry/Provider Status");
@ -93,6 +96,11 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
*/ */
private final StackLayout stackLayout = new StackLayout(); private final StackLayout stackLayout = new StackLayout();
/**
* The rule stack.
*/
private final StackLayout ruleStackLayout = new StackLayout();
/** /**
* Tree Composite * Tree Composite
*/ */
@ -125,8 +133,17 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
/** Data Provider username password composite */ /** Data Provider username password composite */
private DataProviderPasswordComposite passwdComp; private DataProviderPasswordComposite passwdComp;
/** Subscription rules composite */ /** Subscription rules definition composite */
private SubscriptionComposite subComp; private SubscriptionRuleDefinitionComposite subComp;
/** Subscription rules composite for Gridded rules */
private SubscriptionComposite griddedSubRuleComp;
/** Subscription rules composite for Point rules */
private SubscriptionComposite pointSubRuleComp;
/** Rule stack composite */
private Composite ruleStack;
/** /**
* Constructor. * Constructor.
@ -199,6 +216,9 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
stackComp = new Composite(c, SWT.NONE); stackComp = new Composite(c, SWT.NONE);
stackComp.setLayout(stackLayout); stackComp.setLayout(stackLayout);
ruleStack = new Composite(c, SWT.NONE);
ruleStack.setLayout(ruleStackLayout);
createComposites(); createComposites();
createBottomButtons(); createBottomButtons();
} }
@ -223,8 +243,18 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
TreeItem latencyRule = new TreeItem(ruleNode, 1); TreeItem latencyRule = new TreeItem(ruleNode, 1);
latencyRule.setText(SystemManagementSettings.LATENCY_RULES.getName()); latencyRule.setText(SystemManagementSettings.LATENCY_RULES.getName());
TreeItem subscriptionRule = new TreeItem(ruleNode, 2); TreeItem subscriptionRuleNode = new TreeItem(ruleNode, 2);
subscriptionRule.setText(SystemManagementSettings.SUBSCRIPTION_RULES subscriptionRuleNode
.setText(SystemManagementSettings.SUBSCRIPTION_RULES.getName());
TreeItem gridSubscriptionRule = new TreeItem(subscriptionRuleNode, 0);
gridSubscriptionRule
.setText(SystemManagementSettings.GRID_SUBSCRIPTION_RULES
.getName());
TreeItem pointSubscriptionRule = new TreeItem(subscriptionRuleNode, 1);
pointSubscriptionRule
.setText(SystemManagementSettings.POINT_SUBSCRIPTION_RULES
.getName()); .getName());
TreeItem settingsNode = new TreeItem(tree, 1); TreeItem settingsNode = new TreeItem(tree, 1);
@ -256,6 +286,20 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
private void handleSelection(SelectionEvent event) { private void handleSelection(SelectionEvent event) {
TreeItem item = (TreeItem) event.item; TreeItem item = (TreeItem) event.item;
if (item.getText().equals(
SystemManagementSettings.POINT_SUBSCRIPTION_RULES.getName())) {
ruleStackLayout.topControl = compMap
.get(SystemManagementSettings.POINT_SUBSCRIPTION_RULES
.getName());
ruleStack.layout();
} else if (item.getText().equals(
SystemManagementSettings.GRID_SUBSCRIPTION_RULES.getName())) {
ruleStackLayout.topControl = compMap
.get(SystemManagementSettings.GRID_SUBSCRIPTION_RULES
.getName());
ruleStack.layout();
}
for (String key : compMap.keySet()) { for (String key : compMap.keySet()) {
if (item.getText().equals(key)) { if (item.getText().equals(key)) {
stackLayout.topControl = compMap.get(key); stackLayout.topControl = compMap.get(key);
@ -314,12 +358,29 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
gl = new GridLayout(1, false); gl = new GridLayout(1, false);
gd = new GridData(SWT.FILL, SWT.FILL, true, true); gd = new GridData(SWT.FILL, SWT.FILL, true, true);
subComp = new SubscriptionComposite(stackComp, SWT.BORDER); subComp = new SubscriptionRuleDefinitionComposite(stackComp);
subComp.setLayout(gl); subComp.setLayout(gl);
subComp.setLayoutData(gd); subComp.setLayoutData(gd);
compMap.put(SystemManagementSettings.SUBSCRIPTION_RULES.getName(), compMap.put(SystemManagementSettings.SUBSCRIPTION_RULES.getName(),
subComp); subComp);
gl = new GridLayout(1, false);
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
pointSubRuleComp = new PointSubscriptionRuleComposite(stackComp);
pointSubRuleComp.setLayout(gl);
pointSubRuleComp.setLayoutData(gd);
compMap.put(
SystemManagementSettings.POINT_SUBSCRIPTION_RULES.getName(),
pointSubRuleComp);
gl = new GridLayout(1, false);
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
griddedSubRuleComp = new GridSubscriptionRuleComposite(stackComp);
griddedSubRuleComp.setLayout(gl);
griddedSubRuleComp.setLayoutData(gd);
compMap.put(SystemManagementSettings.GRID_SUBSCRIPTION_RULES.getName(),
griddedSubRuleComp);
TreeItem ti = tree.getItem(0); TreeItem ti = tree.getItem(0);
tree.select(ti); tree.select(ti);
} }
@ -398,6 +459,9 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
public void update() { public void update() {
VizApp.runAsync(new Runnable() { VizApp.runAsync(new Runnable() {
@ -406,6 +470,8 @@ public class SystemManagementDlg extends CaveSWTDialog implements IDisplay,
if (!shell.isDisposed()) { if (!shell.isDisposed()) {
systemLatencyComp.loadList(); systemLatencyComp.loadList();
systemPriorityComp.loadList(); systemPriorityComp.loadList();
griddedSubRuleComp.loadConfiguration();
pointSubRuleComp.loadConfiguration();
} }
} }
}); });

View file

@ -21,7 +21,9 @@ package com.raytheon.uf.viz.datadelivery.system;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBContext;
@ -30,9 +32,13 @@ import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; import javax.xml.bind.Unmarshaller;
import com.raytheon.uf.common.datadelivery.bandwidth.IBandwidthService; import com.raytheon.uf.common.datadelivery.bandwidth.IBandwidthService;
import com.raytheon.uf.common.datadelivery.registry.DataType;
import com.raytheon.uf.common.datadelivery.registry.Network; import com.raytheon.uf.common.datadelivery.registry.Network;
import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.Subscription;
import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority;
import com.raytheon.uf.common.datadelivery.service.subscription.GridSubscriptionOverlapConfig;
import com.raytheon.uf.common.datadelivery.service.subscription.PointSubscriptionOverlapConfig;
import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapConfig;
import com.raytheon.uf.common.localization.FileUpdatedMessage; import com.raytheon.uf.common.localization.FileUpdatedMessage;
import com.raytheon.uf.common.localization.ILocalizationFileObserver; import com.raytheon.uf.common.localization.ILocalizationFileObserver;
import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.IPathManager;
@ -71,6 +77,7 @@ import com.raytheon.uf.viz.datadelivery.utils.TypeOperationItems;
* Jan 25, 2013 1528 djohnson Subscription priority is now an enum. * Jan 25, 2013 1528 djohnson Subscription priority is now an enum.
* Jun 04, 2013 223 mpduff Implement point data types. * Jun 04, 2013 223 mpduff Implement point data types.
* Jul 11, 2013 2106 djohnson setAvailableBandwidth service now returns names of subscriptions. * Jul 11, 2013 2106 djohnson setAvailableBandwidth service now returns names of subscriptions.
* Oct 03, 2013 2386 mpduff Add overlap rules.
* *
* </pre> * </pre>
* *
@ -92,6 +99,14 @@ public class SystemRuleManager {
/** Priority rule file */ /** Priority rule file */
private final String PRIORITY_RULE_FILE = RULE_PATH + "priorityRules.xml"; private final String PRIORITY_RULE_FILE = RULE_PATH + "priorityRules.xml";
/** Point overlap rule file */
private final String POINT_SUB_RULE_FILE = RULE_PATH
+ "POINTSubscriptionOverlapRules.xml";
/** Grid overlap rule file */
private final String GRID_SUB_RULE_FILE = RULE_PATH
+ "GRIDSubscriptionOverlapRules.xml";
/** Status Handler */ /** Status Handler */
private final IUFStatusHandler statusHandler = UFStatus private final IUFStatusHandler statusHandler = UFStatus
.getHandler(SystemRuleManager.class); .getHandler(SystemRuleManager.class);
@ -120,6 +135,10 @@ public class SystemRuleManager {
/** Priority Rules XML object */ /** Priority Rules XML object */
private PriorityRulesXML priorityRules; private PriorityRulesXML priorityRules;
/** Map of DataType -> Rules config xml object */
private Map<DataType, SubscriptionOverlapConfig> overlapRulesMap;
/** List of listeners */
private final List<IRulesUpdateListener> listeners = new ArrayList<IRulesUpdateListener>(); private final List<IRulesUpdateListener> listeners = new ArrayList<IRulesUpdateListener>();
/** /**
@ -146,7 +165,10 @@ public class SystemRuleManager {
Class[] classes = new Class[] { RuleXML.class, PriorityRuleXML.class, Class[] classes = new Class[] { RuleXML.class, PriorityRuleXML.class,
LatencyRuleXML.class, LatencyRulesXML.class, LatencyRuleXML.class, LatencyRulesXML.class,
PriorityRulesXML.class, RulesXML.class, OperatorTypes.class, PriorityRulesXML.class, RulesXML.class, OperatorTypes.class,
TypeOperationItems.class, NameOperationItems.class }; TypeOperationItems.class, NameOperationItems.class,
SubscriptionOverlapConfig.class,
GridSubscriptionOverlapConfig.class,
PointSubscriptionOverlapConfig.class };
try { try {
jax = JAXBContext.newInstance(classes); jax = JAXBContext.newInstance(classes);
@ -162,7 +184,6 @@ public class SystemRuleManager {
* Get the names of the priority rules * Get the names of the priority rules
* *
* @return String[] of names * @return String[] of names
* @throws JAXBException
*/ */
public List<String> getPriorityRuleNames() { public List<String> getPriorityRuleNames() {
return getPriorityRules(false).getRuleNames(); return getPriorityRules(false).getRuleNames();
@ -208,12 +229,23 @@ public class SystemRuleManager {
* Get latency file names * Get latency file names
* *
* @return String[] Array of latency rule names * @return String[] Array of latency rule names
* @throws JAXBException
*/ */
public List<String> getLatencyRuleNames() { public List<String> getLatencyRuleNames() {
return getLatencyRules(false).getRuleNames(); return getLatencyRules(false).getRuleNames();
} }
/**
* Get the subscription overlap rules for the provided data type.
*
* @param dataType
* The data type
* @return The Subscription overlap config object
*/
public SubscriptionOverlapConfig getSubscriptionOverlapRules(
DataType dataType) {
return getSubscriptionOverlapRules(false).get(dataType);
}
/** /**
* Save priority rules. * Save priority rules.
* *
@ -459,11 +491,29 @@ public class SystemRuleManager {
return priorityRules; return priorityRules;
} }
/**
* Get the overlap rules
*
* @param reread
* true to reread the file from disk
*
* @return The overlap rules xml object
*/
private Map<DataType, SubscriptionOverlapConfig> getSubscriptionOverlapRules(
boolean reread) {
if (overlapRulesMap == null || reread) {
loadSubscriptionOverlapRules();
}
return overlapRulesMap;
}
/** /**
* Get the default latency value given the cycleTimes. * Get the default latency value given the cycleTimes.
* *
* @param cycleTimes * @param cycleTimes
* @return * list of cycle times
* @return the default latency value
*/ */
public int getDefaultLatency(List<Integer> cycleTimes) { public int getDefaultLatency(List<Integer> cycleTimes) {
DataSetFrequency freq = DataSetFrequency.fromCycleTimes(cycleTimes); DataSetFrequency freq = DataSetFrequency.fromCycleTimes(cycleTimes);
@ -510,7 +560,7 @@ public class SystemRuleManager {
* The subscription * The subscription
* @param cycleTimes * @param cycleTimes
* The available cycle times * The available cycle times
* @return * @return the latency value
*/ */
public int getLatency(Subscription sub, Set<Integer> cycleTimes) { public int getLatency(Subscription sub, Set<Integer> cycleTimes) {
LatencyRulesXML rulesXml = this.getLatencyRules(false); LatencyRulesXML rulesXml = this.getLatencyRules(false);
@ -568,8 +618,10 @@ public class SystemRuleManager {
* Return the lowest priority value defined by the rules. * Return the lowest priority value defined by the rules.
* *
* @param sub * @param sub
* The subscription
* @param cycleTimes * @param cycleTimes
* @return * the cycle times
* @return the priority
*/ */
public SubscriptionPriority getPriority(Subscription sub, public SubscriptionPriority getPriority(Subscription sub,
Set<Integer> cycleTimes) { Set<Integer> cycleTimes) {
@ -671,6 +723,58 @@ public class SystemRuleManager {
getPriorityRules(true); getPriorityRules(true);
} }
/**
* Load the overlap rules.
*/
private void loadSubscriptionOverlapRules() {
overlapRulesMap = new HashMap<DataType, SubscriptionOverlapConfig>();
IPathManager pm = PathManagerFactory.getPathManager();
for (DataType dt : DataType.values()) {
LocalizationFile lf = null;
switch (dt) {
case GRID:
lf = pm.getStaticLocalizationFile(this.GRID_SUB_RULE_FILE);
if (lf != null && lf.exists()) {
GridSubscriptionOverlapConfig config;
try {
config = (GridSubscriptionOverlapConfig) unmarshaller
.unmarshal(lf.getFile());
overlapRulesMap.put(dt, config);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
}
break;
case POINT:
lf = pm.getStaticLocalizationFile(this.POINT_SUB_RULE_FILE);
if (lf != null && lf.exists()) {
PointSubscriptionOverlapConfig config;
try {
config = (PointSubscriptionOverlapConfig) unmarshaller
.unmarshal(lf.getFile());
overlapRulesMap.put(dt, config);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
}
break;
case PDA:
// Not yet implemented
break;
default:
break;
}
if (lf != null && lf.exists()) {
addSubscriptionOverlapRulesFileObserver(lf);
}
}
}
/** /**
* Add a file observer to the latency rules file to get notified when the * Add a file observer to the latency rules file to get notified when the
* file changes. * file changes.
@ -701,6 +805,22 @@ public class SystemRuleManager {
}); });
} }
/**
* Add a file observer to the provided localization file.
*
* @param lf
* The localization file
*/
private void addSubscriptionOverlapRulesFileObserver(LocalizationFile lf) {
lf.addFileUpdatedObserver(new ILocalizationFileObserver() {
@Override
public void fileUpdated(FileUpdatedMessage message) {
loadSubscriptionOverlapRules();
fireUpdates();
}
});
}
/** /**
* Notify the listeners the files changed. * Notify the listeners the files changed.
*/ */
@ -731,4 +851,51 @@ public class SystemRuleManager {
listeners.remove(listener); listeners.remove(listener);
} }
} }
/**
* Save the overlap rules.
*
* @param config
* The data to save
* @param dataType
* The dataType
* @return true if saved correctly
*/
public boolean saveOverlapRule(SubscriptionOverlapConfig config,
DataType dataType) {
if (dataType == null) {
throw new IllegalArgumentException("Invalid dataType, null");
}
final IPathManager pathManager = PathManagerFactory.getPathManager();
LocalizationContext context = pathManager.getContext(
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE);
String fileName = null;
if (dataType == DataType.POINT) {
fileName = this.POINT_SUB_RULE_FILE;
overlapRulesMap.put(dataType, config);
} else if (dataType == DataType.GRID) {
fileName = this.GRID_SUB_RULE_FILE;
overlapRulesMap.put(dataType, config);
} else {
throw new IllegalArgumentException(config.getClass()
+ " Doesn't have any implementation in use");
}
final LocalizationFile configFile = pathManager.getLocalizationFile(
context, fileName);
try {
marshaller.marshal(config, configFile.getFile());
return configFile.save();
} catch (JAXBException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
} catch (LocalizationOpFailedException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
}
return false;
}
} }

View file

@ -26,6 +26,7 @@ import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.MessageBox;
/** /**
* Composite holding the apply and cancel buttons. * Composite holding the apply and cancel buttons.
@ -36,7 +37,8 @@ import org.eclipse.swt.widgets.Composite;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Aug 7, 2013 2180 mpduff Initial creation. * Aug 07, 2013 2180 mpduff Initial creation.
* Oct 03, 2013 2386 mpduff Added apply failed message.
* *
* </pre> * </pre>
* *
@ -100,6 +102,13 @@ public class ApplyCancelComposite extends Composite implements IEnableAction {
public void widgetSelected(SelectionEvent event) { public void widgetSelected(SelectionEvent event) {
if (callback.apply()) { if (callback.apply()) {
enableButtons(false); enableButtons(false);
} else {
MessageBox messageDialog = new MessageBox(getParent()
.getShell(), SWT.ERROR);
messageDialog.setText("Apply Failed");
messageDialog
.setMessage("The apply action failed. See server logs for details.");
messageDialog.open();
} }
} }
}); });

View file

@ -40,6 +40,7 @@ import com.raytheon.uf.common.serialization.JAXBManager;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
/** /**
* Checks subscriptions to see if they would be considered duplicates. * Checks subscriptions to see if they would be considered duplicates.
@ -53,6 +54,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
* May 07, 2013 2000 djohnson Initial creation * May 07, 2013 2000 djohnson Initial creation
* Jun 04, 2013 223 mpduff Get base file if site doesn't exist. * Jun 04, 2013 223 mpduff Get base file if site doesn't exist.
* Sept 23, 2013 2283 dhladky Updated for multiple configs * Sept 23, 2013 2283 dhladky Updated for multiple configs
* Oct 03, 2013 2386 mpduff Moved the subscription overlap rules files into the rules directory.
* *
* </pre> * </pre>
* *
@ -60,7 +62,8 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
* @version 1.0 * @version 1.0
*/ */
public class SubscriptionOverlapService<T extends Time, C extends Coverage> implements ISubscriptionOverlapService<T, C> { public class SubscriptionOverlapService<T extends Time, C extends Coverage>
implements ISubscriptionOverlapService<T, C> {
/** /**
* Base response object implementing {@link ISubscriptionOverlapResponse}. * Base response object implementing {@link ISubscriptionOverlapResponse}.
@ -110,7 +113,8 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT = "SubscriptionOverlapRules.xml"; private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT = "SubscriptionOverlapRules.xml";
private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH = "datadelivery/"; private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH = FileUtil
.join("datadelivery", "systemManagement", "rules");
private final ISubscriptionDuplicateChecker<T, C> duplicateChecker; private final ISubscriptionDuplicateChecker<T, C> duplicateChecker;
@ -170,17 +174,20 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
String fileName = null; String fileName = null;
if (config instanceof PointSubscriptionOverlapConfig) { if (config instanceof PointSubscriptionOverlapConfig) {
fileName = SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH+DataType.POINT.name()+SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT; fileName = SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH
+ DataType.POINT.name()
+ SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT;
} else if (config instanceof GridSubscriptionOverlapConfig) { } else if (config instanceof GridSubscriptionOverlapConfig) {
fileName = SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH+DataType.GRID.name()+SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT; fileName = SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH
+ DataType.GRID.name()
+ SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT;
} else { } else {
throw new IllegalArgumentException(config.getClass()+" Doesn't have any implementation in use"); throw new IllegalArgumentException(config.getClass()
+ " Doesn't have any implementation in use");
} }
final LocalizationFile configFile = pathManager final LocalizationFile configFile = pathManager.getLocalizationFile(
.getLocalizationFile( context, fileName);
context,
fileName);
configFile.jaxbMarshal(config, jaxbManager); configFile.jaxbMarshal(config, jaxbManager);
} }
@ -207,13 +214,15 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
/** /**
* Process a set of Gridded subscriptions for duplication; * Process a set of Gridded subscriptions for duplication;
*
* @param config * @param config
* @param sub1 * @param sub1
* @param sub2 * @param sub2
* @return * @return
*/ */
private SubscriptionOverlapResponse processGriddedSubscriptionOverlap(GridSubscriptionOverlapConfig config, Subscription<T, C> sub1, Subscription<T, C> sub2) { private SubscriptionOverlapResponse processGriddedSubscriptionOverlap(
GridSubscriptionOverlapConfig config, Subscription<T, C> sub1,
Subscription<T, C> sub2) {
final int parameterDuplicationPercent = duplicateChecker final int parameterDuplicationPercent = duplicateChecker
.getParameterDuplicationPercent(sub1, sub2); .getParameterDuplicationPercent(sub1, sub2);
final int forecastHourDuplicationPercent = duplicateChecker final int forecastHourDuplicationPercent = duplicateChecker
@ -237,13 +246,15 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
/*** /***
* Process a set of Point subscriptions for duplication * Process a set of Point subscriptions for duplication
*
* @param config * @param config
* @param sub1 * @param sub1
* @param sub2 * @param sub2
* @return * @return
*/ */
private SubscriptionOverlapResponse processPointSubscriptionOverlap(PointSubscriptionOverlapConfig config, Subscription<T, C> sub1, Subscription<T, C> sub2) { private SubscriptionOverlapResponse processPointSubscriptionOverlap(
PointSubscriptionOverlapConfig config, Subscription<T, C> sub1,
Subscription<T, C> sub2) {
final int parameterDuplicationPercent = duplicateChecker final int parameterDuplicationPercent = duplicateChecker
.getParameterDuplicationPercent(sub1, sub2); .getParameterDuplicationPercent(sub1, sub2);
final int timeDuplicationPercent = duplicateChecker final int timeDuplicationPercent = duplicateChecker
@ -252,8 +263,8 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
.getSpatialDuplicationPercent(sub1, sub2); .getSpatialDuplicationPercent(sub1, sub2);
final boolean overlaps = config.isOverlapping( final boolean overlaps = config.isOverlapping(
parameterDuplicationPercent, timeDuplicationPercent, parameterDuplicationPercent, timeDuplicationPercent, 0,
0, spatialDuplicationPercent); spatialDuplicationPercent);
final boolean duplicate = (parameterDuplicationPercent == ONE_HUNDRED_PERCENT) final boolean duplicate = (parameterDuplicationPercent == ONE_HUNDRED_PERCENT)
&& (timeDuplicationPercent == ONE_HUNDRED_PERCENT) && (timeDuplicationPercent == ONE_HUNDRED_PERCENT)
@ -264,6 +275,7 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
/** /**
* Gets the overlap config file by type * Gets the overlap config file by type
*
* @param type * @param type
* @return * @return
*/ */
@ -273,13 +285,15 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
LocalizationFile localizationFile = null; LocalizationFile localizationFile = null;
SubscriptionOverlapConfig config = null; SubscriptionOverlapConfig config = null;
localizationFile = pathManager localizationFile = pathManager
.getStaticLocalizationFile(SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH+type.name()+SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT); .getStaticLocalizationFile(SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH
+ type.name() + SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT);
try { try {
if (!localizationFile.exists()) { if (!localizationFile.exists()) {
throw new MissingResourceException(localizationFile.getName() throw new MissingResourceException(localizationFile.getName()
+ " does not exist.", + " does not exist.",
SubscriptionOverlapConfig.class.getName(), "Not yet implemented!"); SubscriptionOverlapConfig.class.getName(),
"Not yet implemented!");
} }
if (type == DataType.GRID) { if (type == DataType.GRID) {
@ -293,12 +307,14 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
} }
} catch (Exception e) { } catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, UNABLE_TO_UNMARSHAL, e.getLocalizedMessage()); statusHandler.handle(Priority.PROBLEM, UNABLE_TO_UNMARSHAL,
e.getLocalizedMessage());
// this a fall back so at least some checking gets done // this a fall back so at least some checking gets done
if (type == DataType.GRID) { if (type == DataType.GRID) {
config = new GridSubscriptionOverlapConfig().getNeverOverlaps(); config = new GridSubscriptionOverlapConfig().getNeverOverlaps();
} else if (type == DataType.POINT) { } else if (type == DataType.POINT) {
config = new PointSubscriptionOverlapConfig().getNeverOverlaps(); config = new PointSubscriptionOverlapConfig()
.getNeverOverlaps();
} }
} }
@ -307,13 +323,15 @@ public class SubscriptionOverlapService<T extends Time, C extends Coverage> impl
/** /**
* Gets the SubscriptionOverlapResponse by type * Gets the SubscriptionOverlapResponse by type
*
* @param config * @param config
* @param sub1 * @param sub1
* @param sub2 * @param sub2
* @return * @return
*/ */
private SubscriptionOverlapResponse getOverlap(SubscriptionOverlapConfig config, Subscription<T, C> sub1, Subscription<T,C> sub2) { private SubscriptionOverlapResponse getOverlap(
SubscriptionOverlapConfig config, Subscription<T, C> sub1,
Subscription<T, C> sub2) {
SubscriptionOverlapResponse response = null; SubscriptionOverlapResponse response = null;
DataType type = sub1.getDataSetType(); DataType type = sub1.getDataSetType();