Issue #1474 Fixed MetarPrecipResourceData and LightningResourceData so updates do not required requery. Made an AutoUpdater per plugin so they process independently of each other.
Amend: Only register product alerts in thin client if JMS is not disabled Change-Id: Ic46daf57ef3ede3aad2a2f067e9764f85f7df9a2 Former-commit-id:b6a29c38a5
[formerly 115dc26748e0779b4c67cc74fe08c5bf17542632] Former-commit-id:9655d64069
This commit is contained in:
parent
3d838584ed
commit
a8dc166a1f
12 changed files with 183 additions and 129 deletions
|
@ -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<String, Class<PluginDataObject>> defMap;
|
||||
private Map<String, Class<PluginDataObject>> defMap = new HashMap<String, Class<PluginDataObject>>();
|
||||
|
||||
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<String, String> pluginRecordMap = (Map<String, String>) ThriftClient
|
||||
.sendRequest(req);
|
||||
Map<String, Class<PluginDataObject>> newDefMap = new HashMap<String, Class<PluginDataObject>>(
|
||||
pluginRecordMap.size());
|
||||
for (Map.Entry<String, String> entry : pluginRecordMap.entrySet()) {
|
||||
String pluginName = entry.getKey();
|
||||
String record = entry.getValue();
|
||||
if (record != null) {
|
||||
try {
|
||||
Class<PluginDataObject> clazz = (Class<PluginDataObject>) 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<String, String> pluginRecordMap = (Map<String, String>) ThriftClient
|
||||
.sendRequest(req);
|
||||
for (Map.Entry<String, String> entry : pluginRecordMap.entrySet()) {
|
||||
String pluginName = entry.getKey();
|
||||
String record = entry.getValue();
|
||||
if (record != null) {
|
||||
try {
|
||||
Class<PluginDataObject> clazz = (Class<PluginDataObject>) 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<String> getSupportedPlugins() {
|
||||
return new TreeSet<String>(defMap.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a map of the fields and values that compose a given dataURI
|
||||
*
|
||||
|
@ -123,7 +128,6 @@ public class RecordFactory {
|
|||
*/
|
||||
public Map<String, Object> loadMapFromUri(String dataURI)
|
||||
throws VizException {
|
||||
|
||||
// If no dataURI return
|
||||
if (dataURI == null) {
|
||||
return null;
|
||||
|
@ -181,10 +185,10 @@ public class RecordFactory {
|
|||
*/
|
||||
public Class<PluginDataObject> getPluginClass(String pluginName)
|
||||
throws VizException {
|
||||
if (defMap == null) {
|
||||
loadDefMap();
|
||||
Class<PluginDataObject> retVal = null;
|
||||
if (defMap != null) {
|
||||
retVal = defMap.get(pluginName);
|
||||
}
|
||||
Class<PluginDataObject> retVal = defMap.get(pluginName);
|
||||
if (retVal == null) {
|
||||
throw new NoPluginException("Can't find record class for "
|
||||
+ pluginName + " plugin");
|
||||
|
|
|
@ -288,7 +288,7 @@ public abstract class AbstractRequestableResourceData extends
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.fireChangeListeners(ChangeType.DATA_UPDATE, updateData);
|
||||
}
|
||||
|
||||
|
@ -683,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
|
||||
|
@ -724,10 +723,6 @@ public abstract class AbstractRequestableResourceData extends
|
|||
return false;
|
||||
}
|
||||
|
||||
if (isUpdatingOnMetadataOnly != other.isUpdatingOnMetadataOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isObjectsEqual(metadataMap, other.metadataMap)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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<String> datauris) {
|
||||
for (String datauri : datauris) {
|
||||
getInstance().processDataURI(datauri);
|
||||
/**
|
||||
* Processes the DataURIs as alert messages
|
||||
*
|
||||
* @param datauris
|
||||
*/
|
||||
public static void processDataURIAlerts(Collection<String> datauris) {
|
||||
getInstance().processDataURIs(datauris);
|
||||
}
|
||||
|
||||
private synchronized void processDataURIs(Collection<String> 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<String, Object> 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<String, Object> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -298,7 +298,7 @@ public class GridUpdater implements IAlertObserver {
|
|||
}
|
||||
}
|
||||
myUpdates.addAll(datauris);
|
||||
ProductAlertObserver.processDerivedAlerts(datauris);
|
||||
ProductAlertObserver.processDataURIAlerts(datauris);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -157,7 +157,11 @@ public class MetarPrecipResource extends
|
|||
@Override
|
||||
protected void paintInternal(IGraphicsTarget target,
|
||||
PaintProperties paintProps) throws VizException {
|
||||
List<RenderablePrecipData> precips = data.get(paintProps.getDataTime());
|
||||
DataTime time = paintProps.getDataTime();
|
||||
if (time == null) {
|
||||
return;
|
||||
}
|
||||
List<RenderablePrecipData> precips = getPrecipData(time);
|
||||
if (precips == null) {
|
||||
dataProcessJob.schedule();
|
||||
return;
|
||||
|
@ -201,6 +205,19 @@ public class MetarPrecipResource extends
|
|||
target.drawStrings(strings);
|
||||
}
|
||||
|
||||
private List<RenderablePrecipData> getPrecipData(DataTime time) {
|
||||
List<RenderablePrecipData> currData = null;
|
||||
synchronized (data) {
|
||||
currData = data.get(time);
|
||||
}
|
||||
if (currData != null) {
|
||||
synchronized (currData) {
|
||||
return new ArrayList<RenderablePrecipData>(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<RenderablePrecipData> precips = data.get(descriptor
|
||||
List<RenderablePrecipData> 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<RenderablePrecipData> 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<RenderablePrecipData> 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<RenderablePrecipData> iter = entry.getValue().iterator();
|
||||
while (iter.hasNext()) {
|
||||
if (newStations.contains(iter.next().getStationName())) {
|
||||
iter.remove();
|
||||
synchronized (entry.getValue()) {
|
||||
Iterator<RenderablePrecipData> 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<PrecipData> precips) {
|
||||
if (precips.isEmpty()) {
|
||||
if (!dataTimes.contains(time)) {
|
||||
List<RenderablePrecipData> newPrecips = Collections.emptyList();
|
||||
data.put(time, newPrecips);
|
||||
synchronized (data) {
|
||||
List<RenderablePrecipData> newPrecips = Collections
|
||||
.emptyList();
|
||||
data.put(time, newPrecips);
|
||||
}
|
||||
dataTimes.add(time);
|
||||
}
|
||||
}
|
||||
if (data.containsKey(time)) {
|
||||
precips = new ArrayList<PrecipData>(precips);
|
||||
for (RenderablePrecipData pData : data.get(time)) {
|
||||
precips.add(pData);
|
||||
}
|
||||
precips.addAll(getPrecipData(time));
|
||||
}
|
||||
Collections.sort(precips, new Comparator<PrecipData>() {
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<AbstractRequestableData> cacheSet = new HashSet<AbstractRequestableData>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ public class BundleLoader extends Job {
|
|||
if (containerPanes.length != bundleDisplays.length) {
|
||||
boolean success = ensureOneToOne(container, bundle);
|
||||
containerPanes = container.getDisplayPanes();
|
||||
if (success) {
|
||||
if (success == false) {
|
||||
throw new VizException("Unable to load "
|
||||
+ bundleDisplays.length
|
||||
+ " displays onto container with "
|
||||
|
|
Loading…
Add table
Reference in a new issue