593 lines
25 KiB
Java
593 lines
25 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*/
|
|
package com.tridium.sys.metrics;
|
|
|
|
import com.tridium.sys.metrics.GlobalGroup;
|
|
import com.tridium.sys.metrics.Group;
|
|
import com.tridium.sys.metrics.IMetricResource;
|
|
import com.tridium.sys.metrics.SubGroup;
|
|
import com.tridium.sys.resource.ResourceReport;
|
|
import java.text.DecimalFormat;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.Stack;
|
|
import java.util.TreeSet;
|
|
import javax.baja.collection.BIList;
|
|
import javax.baja.license.Feature;
|
|
import javax.baja.naming.BOrd;
|
|
import javax.baja.security.BICredentials;
|
|
import javax.baja.security.BPassword;
|
|
import javax.baja.spy.Spy;
|
|
import javax.baja.spy.SpyWriter;
|
|
import javax.baja.sys.BAbsTime;
|
|
import javax.baja.sys.BComplex;
|
|
import javax.baja.sys.BLink;
|
|
import javax.baja.sys.BObject;
|
|
import javax.baja.sys.BString;
|
|
import javax.baja.sys.Property;
|
|
import javax.baja.sys.SlotCursor;
|
|
import javax.baja.sys.Sys;
|
|
import javax.baja.sys.Type;
|
|
import javax.baja.util.BNotification;
|
|
import javax.baja.util.BTypeSpec;
|
|
|
|
public final class Metrics {
|
|
private static final DecimalFormat DF = new DecimalFormat("###,###,###");
|
|
private static Object lock = new Object();
|
|
private static Type scheduleType;
|
|
private static String recountLastRun;
|
|
private static String recountLastFail;
|
|
private static String recountLastFailReason;
|
|
private static GlobalGroup global;
|
|
private static Set subGroups;
|
|
private static Map moduleGroups;
|
|
private static int historyExtCount;
|
|
public static final String HISTORY_FAULT_CAUSE = "Exceeded Global Capacity history limit.";
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
public static final String incrementNetwork(BComplex bComplex) {
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
return Metrics.incrementNetwork(bComplex, global, moduleGroups);
|
|
}
|
|
}
|
|
|
|
private static final String incrementNetwork(BComplex bComplex, GlobalGroup globalGroup, Map map) {
|
|
boolean bl = false;
|
|
if (globalGroup.excludedNetworks.contains((Object)bComplex.getType().getModule().getModuleName())) {
|
|
bl = true;
|
|
} else {
|
|
++globalGroup.networks.used;
|
|
}
|
|
Group group = Metrics.findSubGroup(bComplex, map);
|
|
if (group == null) {
|
|
return !bl && globalGroup.networks.used > globalGroup.networks.limit ? globalGroup.featureName : null;
|
|
}
|
|
++group.networks.used;
|
|
if (globalGroup.networks.used > globalGroup.networks.limit) {
|
|
return group.networks.used > group.networks.limit ? globalGroup.featureName + ',' + group.featureName : globalGroup.featureName;
|
|
}
|
|
return group.networks.used > group.networks.limit ? group.featureName : null;
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
public static final String incrementDevice(BComplex bComplex) {
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
return Metrics.incrementDevice(bComplex, global, moduleGroups);
|
|
}
|
|
}
|
|
|
|
private static final String incrementDevice(BComplex bComplex, GlobalGroup globalGroup, Map map) {
|
|
boolean bl = false;
|
|
if (globalGroup.excludedDevices.contains((Object)bComplex.getType().getModule().getModuleName())) {
|
|
bl = true;
|
|
} else {
|
|
++globalGroup.devices.used;
|
|
}
|
|
Group group = Metrics.findSubGroup(bComplex, map);
|
|
if (group == null) {
|
|
return !bl && globalGroup.devices.used > globalGroup.devices.limit ? globalGroup.featureName : null;
|
|
}
|
|
++group.devices.used;
|
|
if (globalGroup.devices.used > globalGroup.devices.limit) {
|
|
return group.devices.used > group.devices.limit ? globalGroup.featureName + ',' + group.featureName : globalGroup.featureName;
|
|
}
|
|
return group.devices.used > group.devices.limit ? group.featureName : null;
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
public static final String incrementPoint(BComplex bComplex) {
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
return Metrics.incrementPoint(bComplex, global, moduleGroups);
|
|
}
|
|
}
|
|
|
|
private static final String incrementPoint(BComplex bComplex, GlobalGroup globalGroup, Map map) {
|
|
boolean bl = false;
|
|
if (globalGroup.excludedPoints.contains((Object)bComplex.getType().getModule().getModuleName())) {
|
|
bl = true;
|
|
} else {
|
|
++globalGroup.points.used;
|
|
}
|
|
Group group = Metrics.findSubGroup(bComplex, map);
|
|
if (group == null) {
|
|
return !bl && globalGroup.points.used > globalGroup.points.limit ? globalGroup.featureName : null;
|
|
}
|
|
++group.points.used;
|
|
if (globalGroup.points.used > globalGroup.points.limit) {
|
|
return group.points.used > group.points.limit ? globalGroup.featureName + ',' + group.featureName : globalGroup.featureName;
|
|
}
|
|
return group.points.used > group.points.limit ? group.featureName : null;
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
public static final boolean incrementLink() {
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
++Metrics.global.links.used;
|
|
if (Metrics.global.links.used == Metrics.global.links.limit + 1 && Sys.getStation() != null) {
|
|
BNotification bNotification = new BNotification();
|
|
bNotification.add("title", BString.make("Capacity Licensing"));
|
|
bNotification.add("message", BString.make("Exceeded Link Limit"));
|
|
bNotification.raise(true);
|
|
}
|
|
boolean bl = false;
|
|
if (Metrics.global.links.used > Metrics.global.links.limit) return bl;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
public static final boolean incrementHistory() {
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
if (Metrics.global.histories.used < Metrics.global.histories.limit) {
|
|
++Metrics.global.histories.used;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static final boolean incrementSchedule(BComplex bComplex) {
|
|
return Metrics.incrementSchedule(bComplex, global);
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
private static final boolean incrementSchedule(BComplex bComplex, GlobalGroup globalGroup) {
|
|
Property property = bComplex.getPropertyInParent();
|
|
Metrics.ensureScheduleTypeLoaded();
|
|
if (!(bComplex instanceof IMetricResource)) {
|
|
return true;
|
|
}
|
|
if (bComplex.getParent() != null && bComplex.getParent().getType().is(scheduleType) && property.isFrozen()) {
|
|
return true;
|
|
}
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
++globalGroup.schedules.used;
|
|
boolean bl = false;
|
|
if (globalGroup.schedules.used > globalGroup.schedules.limit) return bl;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private static final void ensureScheduleTypeLoaded() {
|
|
if (scheduleType == null) {
|
|
try {
|
|
scheduleType = BTypeSpec.make("schedule", "CompositeSchedule").getResolvedType();
|
|
}
|
|
catch (Exception exception) {}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
public static final boolean isUsingCapacityLicensing() {
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
boolean bl = false;
|
|
if (Metrics.global.isGlobalEnabled) return true;
|
|
if (moduleGroups.size() <= 0) return bl;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public static final void writeToResourceReport(ResourceReport resourceReport) {
|
|
boolean bl = false;
|
|
if (Metrics.global.isGlobalEnabled) {
|
|
bl = true;
|
|
resourceReport.put("globalCapacity.networks", Metrics.getDisplayUsed(Metrics.global.networks) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.networks) + ')');
|
|
resourceReport.put("globalCapacity.devices", Metrics.getDisplayUsed(Metrics.global.devices) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.devices) + ')');
|
|
resourceReport.put("globalCapacity.points", Metrics.getDisplayUsed(Metrics.global.points) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.points) + ')');
|
|
resourceReport.put("globalCapacity.links", Metrics.getDisplayUsed(Metrics.global.links) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.links) + ')');
|
|
if (Metrics.global.histories.used > historyExtCount) {
|
|
resourceReport.put("globalCapacity.histories", Metrics.getDisplayUsed(Metrics.global.histories) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.histories) + ')');
|
|
} else {
|
|
resourceReport.put("globalCapacity.histories", DF.format(historyExtCount) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.histories) + ')');
|
|
}
|
|
resourceReport.put("globalCapacity.schedules", Metrics.getDisplayUsed(Metrics.global.schedules) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.schedules) + ')');
|
|
}
|
|
if (moduleGroups.size() > 0) {
|
|
bl = true;
|
|
Iterator iterator = subGroups.iterator();
|
|
while (iterator.hasNext()) {
|
|
SubGroup subGroup = (SubGroup)iterator.next();
|
|
resourceReport.put(subGroup.featureName + ".networks", Metrics.getDisplayUsed(subGroup.networks) + " (Limit: " + Metrics.getDisplayLimit(subGroup.networks) + ')');
|
|
resourceReport.put(subGroup.featureName + ".devices", Metrics.getDisplayUsed(subGroup.devices) + " (Limit: " + Metrics.getDisplayLimit(subGroup.devices) + ')');
|
|
resourceReport.put(subGroup.featureName + ".points", Metrics.getDisplayUsed(subGroup.points) + " (Limit: " + Metrics.getDisplayLimit(subGroup.points) + ')');
|
|
}
|
|
}
|
|
if (bl) {
|
|
resourceReport.put("capacityLicensing.recountLastRun", recountLastRun);
|
|
resourceReport.put("capacityLicensing.recountLastFail", recountLastFail);
|
|
resourceReport.put("capacityLicensing.recountLastFailReason", recountLastFailReason);
|
|
}
|
|
}
|
|
|
|
private static final Group findSubGroup(BComplex bComplex, Map map) {
|
|
Type type = bComplex.getType();
|
|
return (Group)map.get(type.getModule().getModuleName());
|
|
}
|
|
|
|
private static final String getDisplayUsed(Group.Count count) {
|
|
return DF.format(count.used);
|
|
}
|
|
|
|
private static final String getDisplayLimit(Group.Count count) {
|
|
return count.limit == Integer.MAX_VALUE ? "none" : DF.format(count.limit);
|
|
}
|
|
|
|
private static final void loadSubGroups(Set set, Map map) {
|
|
Feature[] featureArray = Sys.getLicenseManager().getFeatures();
|
|
int n = 0;
|
|
while (n < featureArray.length) {
|
|
Feature feature = featureArray[n];
|
|
if (feature.getVendorName().toLowerCase().equals("tridium") && feature.getFeatureName().toLowerCase().startsWith("driverCapacity".toLowerCase())) {
|
|
SubGroup subGroup = new SubGroup(feature);
|
|
set.add(subGroup);
|
|
int n2 = 0;
|
|
while (n2 < subGroup.modules.length) {
|
|
map.put(subGroup.modules[n2], subGroup);
|
|
++n2;
|
|
}
|
|
}
|
|
++n;
|
|
}
|
|
}
|
|
|
|
static {
|
|
recountLastRun = "never";
|
|
recountLastFail = "never";
|
|
recountLastFailReason = "";
|
|
global = new GlobalGroup();
|
|
subGroups = new TreeSet();
|
|
moduleGroups = new HashMap();
|
|
historyExtCount = 0;
|
|
Metrics.loadSubGroups(subGroups, moduleGroups);
|
|
}
|
|
|
|
public static final class Recount
|
|
extends Thread {
|
|
private static final int INTERVAL = 30000;
|
|
private static Type NETWORK_TYPE = null;
|
|
private static Type DEVICE_TYPE = null;
|
|
private static Type POINT_TYPE = null;
|
|
private static Set subGroupsBucket = new TreeSet();
|
|
private static Map moduleGroupsBucket = new HashMap();
|
|
private SlotCursor current;
|
|
private BComplex root;
|
|
private boolean componentOnly;
|
|
private Stack nodeStack;
|
|
private GlobalGroup globalBucket;
|
|
|
|
public final void run() {
|
|
if (Metrics.isUsingCapacityLicensing()) {
|
|
try {
|
|
DEVICE_TYPE = BTypeSpec.make("driver", "Device").getResolvedType();
|
|
}
|
|
catch (Exception exception) {}
|
|
try {
|
|
NETWORK_TYPE = BTypeSpec.make("driver", "DeviceNetwork").getResolvedType();
|
|
}
|
|
catch (Exception exception) {}
|
|
try {
|
|
POINT_TYPE = BTypeSpec.make("driver", "ProxyExt").getResolvedType();
|
|
}
|
|
catch (Exception exception) {}
|
|
Metrics.ensureScheduleTypeLoaded();
|
|
this.globalBucket = new GlobalGroup();
|
|
Metrics.loadSubGroups(Recount.subGroupsBucket, Recount.moduleGroupsBucket);
|
|
boolean bl = false;
|
|
if (this.globalBucket.links.limit == Integer.MAX_VALUE) {
|
|
bl = true;
|
|
}
|
|
this.componentOnly = bl;
|
|
while (true) {
|
|
try {
|
|
Thread.sleep(30000L);
|
|
this.root = Sys.getStation();
|
|
this.current = null;
|
|
this.globalBucket.networks.used = 0;
|
|
this.globalBucket.devices.used = 0;
|
|
this.globalBucket.points.used = 0;
|
|
this.globalBucket.histories.used = 0;
|
|
this.globalBucket.links.used = 0;
|
|
this.globalBucket.schedules.used = 0;
|
|
Iterator iterator = subGroupsBucket.iterator();
|
|
while (iterator.hasNext()) {
|
|
SubGroup subGroup = (SubGroup)iterator.next();
|
|
subGroup.networks.used = 0;
|
|
subGroup.devices.used = 0;
|
|
subGroup.points.used = 0;
|
|
}
|
|
this.count();
|
|
recountLastRun = BAbsTime.make().toString();
|
|
}
|
|
catch (Exception exception) {
|
|
recountLastFail = BAbsTime.make().toString();
|
|
recountLastFailReason = exception.toString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
private final void count() {
|
|
BObject bObject;
|
|
while (this.nextImpl()) {
|
|
bObject = this.get();
|
|
if (bObject instanceof BPassword || bObject instanceof BICredentials) continue;
|
|
this.checkMatch(bObject);
|
|
}
|
|
bObject = BOrd.make("history:|bql:select * from sys.histories");
|
|
BIList bIList = (BIList)((Object)((BOrd)bObject).resolve().get());
|
|
BOrd bOrd = BOrd.make("station:|slot:/|bql:select * from history:HistoryExt where status.isFault AND faultCause like '%Exceeded Global Capacity history limit.%'");
|
|
BIList bIList2 = (BIList)((Object)bOrd.resolve().get());
|
|
BOrd bOrd2 = BOrd.make("station:|slot:/|bql:select * from driver:HistoryImport where status.isFault and faultCause like '%Exceeded Global Capacity history limit.%'");
|
|
BIList bIList3 = (BIList)((Object)bOrd2.resolve().get());
|
|
this.globalBucket.histories.used = bIList.size();
|
|
historyExtCount = bIList.size() + bIList2.size() + bIList3.size();
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
global.networks.used = this.globalBucket.networks.used;
|
|
global.devices.used = this.globalBucket.devices.used;
|
|
global.points.used = this.globalBucket.points.used;
|
|
if (!this.componentOnly) {
|
|
global.links.used = this.globalBucket.links.used;
|
|
}
|
|
global.schedules.used = this.globalBucket.schedules.used;
|
|
global.histories.used = this.globalBucket.histories.used;
|
|
Iterator iterator = subGroupsBucket.iterator();
|
|
while (iterator.hasNext()) {
|
|
SubGroup subGroup = (SubGroup)iterator.next();
|
|
Group group = (Group)moduleGroups.get(subGroup.modules[0]);
|
|
group.networks.used = subGroup.networks.used;
|
|
group.devices.used = subGroup.devices.used;
|
|
group.points.used = subGroup.points.used;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
private final void checkMatch(BObject bObject) {
|
|
if (bObject.getType().is(NETWORK_TYPE)) {
|
|
Metrics.incrementNetwork((BComplex)bObject, this.globalBucket, Recount.moduleGroupsBucket);
|
|
} else if (bObject.getType().is(DEVICE_TYPE)) {
|
|
Metrics.incrementDevice((BComplex)bObject, this.globalBucket, Recount.moduleGroupsBucket);
|
|
} else if (bObject.getType().is(POINT_TYPE)) {
|
|
Metrics.incrementPoint((BComplex)bObject, this.globalBucket, Recount.moduleGroupsBucket);
|
|
} else if (bObject.getType().is(scheduleType)) {
|
|
Metrics.incrementSchedule((BComplex)bObject, this.globalBucket);
|
|
} else if (bObject instanceof BLink) {
|
|
++this.globalBucket.links.used;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Unable to fully structure code
|
|
*/
|
|
private final boolean nextImpl() {
|
|
if (this.current == null) {
|
|
if (!this.root.isComplex()) {
|
|
return false;
|
|
}
|
|
this.current = this.root.asComplex().getProperties();
|
|
if (this.componentOnly) {
|
|
return this.current.nextComponent();
|
|
}
|
|
return this.current.next();
|
|
}
|
|
var1_1 = null;
|
|
var2_2 = null;
|
|
var3_3 = false;
|
|
if (this.componentOnly != false ? this.current.get().isComponent() != false : this.current.get().isComplex() != false) {
|
|
var1_1 = (BComplex)this.current.get();
|
|
var2_2 = var1_1.getProperties();
|
|
if (this.componentOnly) {
|
|
if (var2_2.nextComponent()) {
|
|
var3_3 = true;
|
|
}
|
|
} else if (var2_2.next()) {
|
|
var3_3 = true;
|
|
}
|
|
}
|
|
if (!var3_3) ** GOTO lbl30
|
|
if (this.nodeStack == null) {
|
|
this.nodeStack = new Stack<E>();
|
|
}
|
|
this.nodeStack.push(this.current);
|
|
this.current = var2_2;
|
|
return true;
|
|
lbl-1000:
|
|
// 1 sources
|
|
|
|
{
|
|
if (this.nodeStack == null || this.nodeStack.empty()) {
|
|
return false;
|
|
}
|
|
this.current = (SlotCursor)this.nodeStack.pop();
|
|
lbl30:
|
|
// 2 sources
|
|
|
|
** while (!(this.componentOnly != false ? this.current.nextComponent() != false : this.current.next() != false))
|
|
}
|
|
lbl31:
|
|
// 1 sources
|
|
|
|
return true;
|
|
}
|
|
|
|
private final BObject get() {
|
|
return this.current.get();
|
|
}
|
|
|
|
public Recount() {
|
|
super("Nre:Metrics.Recount");
|
|
this.setDaemon(true);
|
|
}
|
|
}
|
|
|
|
public static class MetricSpy
|
|
extends Spy {
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
* Enabled aggressive block sorting
|
|
* Enabled unnecessary exception pruning
|
|
* Enabled aggressive exception aggregation
|
|
*/
|
|
public void write(SpyWriter spyWriter) {
|
|
Object object = lock;
|
|
synchronized (object) {
|
|
this.writeRecountTable(spyWriter);
|
|
this.writeGroup(spyWriter, global);
|
|
Iterator iterator = subGroups.iterator();
|
|
while (iterator.hasNext()) {
|
|
this.writeGroup(spyWriter, (SubGroup)iterator.next());
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
private final void writeRecountTable(SpyWriter spyWriter) {
|
|
spyWriter.startTable(true);
|
|
spyWriter.trTitle("Recount", 3);
|
|
spyWriter.w("<tr>");
|
|
spyWriter.w("<td>recountLastRun</td>");
|
|
spyWriter.w("<td>").w(recountLastRun).w("</td>");
|
|
spyWriter.w("</tr>\n");
|
|
spyWriter.w("<tr>");
|
|
spyWriter.w("<td>recountLastFail</td>");
|
|
spyWriter.w("<td>").w(recountLastFail).w("</td>");
|
|
spyWriter.w("</tr>\n");
|
|
spyWriter.w("<tr>");
|
|
spyWriter.w("<td>recountLastFailReason</td>");
|
|
spyWriter.w("<td>").w(recountLastFailReason).w("</td>");
|
|
spyWriter.w("</tr>\n");
|
|
spyWriter.endTable();
|
|
spyWriter.w("<p/><p/>");
|
|
}
|
|
|
|
private final void writeGroup(SpyWriter spyWriter, Group group) {
|
|
spyWriter.startTable(true);
|
|
if (group.isGlobal()) {
|
|
spyWriter.trTitle("Global Capacity", 3);
|
|
if (((GlobalGroup)group).excludedNetworks.size() > 0) {
|
|
spyWriter.trTitle("Excluded Networks: " + ((GlobalGroup)group).excludedNetworks.toString(), 3);
|
|
}
|
|
if (((GlobalGroup)group).excludedDevices.size() > 0) {
|
|
spyWriter.trTitle("Excluded Devices: " + ((GlobalGroup)group).excludedDevices.toString(), 3);
|
|
}
|
|
if (((GlobalGroup)group).excludedPoints.size() > 0) {
|
|
spyWriter.trTitle("Excluded Points: " + ((GlobalGroup)group).excludedPoints.toString(), 3);
|
|
}
|
|
} else {
|
|
String string = group.featureName.substring("driverCapacity".length());
|
|
spyWriter.trTitle("Driver Capacity: " + string, 3);
|
|
SubGroup subGroup = (SubGroup)group;
|
|
String string2 = Arrays.asList(subGroup.modules).toString();
|
|
string2 = string2.substring(1, string2.length() - 1);
|
|
spyWriter.trTitle("Modules: " + string2, 3);
|
|
}
|
|
spyWriter.w("<tr>");
|
|
spyWriter.w("<th>Type</th>");
|
|
spyWriter.w("<th>Limit</th>");
|
|
spyWriter.w("<th>Used</th>");
|
|
spyWriter.w("</tr>\n");
|
|
this.writeRow(spyWriter, "Networks", group.networks);
|
|
this.writeRow(spyWriter, "Devices", group.devices);
|
|
this.writeRow(spyWriter, "Points", group.points);
|
|
if (group.isGlobal()) {
|
|
this.writeRow(spyWriter, "Links", ((GlobalGroup)group).links);
|
|
if (global.histories.used > historyExtCount) {
|
|
this.writeRow(spyWriter, "Histories", ((GlobalGroup)group).histories);
|
|
} else {
|
|
MetricSpy.writeRow(spyWriter, "Histories", Metrics.getDisplayLimit(((GlobalGroup)group).histories), DF.format(historyExtCount));
|
|
}
|
|
this.writeRow(spyWriter, "Schedules", ((GlobalGroup)group).schedules);
|
|
}
|
|
spyWriter.endTable();
|
|
spyWriter.w("<p/><p/>");
|
|
}
|
|
|
|
private final void writeRow(SpyWriter spyWriter, String string, Group.Count count) {
|
|
String string2 = Metrics.getDisplayLimit(count);
|
|
MetricSpy.writeRow(spyWriter, string, string2, Metrics.getDisplayUsed(count));
|
|
}
|
|
|
|
private static final void writeRow(SpyWriter spyWriter, String string, String string2, String string3) {
|
|
spyWriter.w("<tr>");
|
|
spyWriter.w("<td align='left' nowrap='true'>").w(string).w("</td>");
|
|
spyWriter.w("<td align='right' nowrap='true'>").w(string2).w("</td>");
|
|
spyWriter.w("<td align='right' nowrap='true'>").w(string3).w("</td>");
|
|
spyWriter.w("</tr>\n");
|
|
}
|
|
}
|
|
}
|
|
|