/*
* Copyright 2015 the original author or authors.
* @https://github.com/scouter-project/scouter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package scouter.client.counter.views;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;
import org.csstudio.swt.xygraph.dataprovider.CircularBufferDataProvider;
import org.csstudio.swt.xygraph.dataprovider.Sample;
import org.csstudio.swt.xygraph.figures.Trace;
import org.csstudio.swt.xygraph.figures.Trace.PointStyle;
import org.csstudio.swt.xygraph.figures.Trace.TraceType;
import org.csstudio.swt.xygraph.figures.XYGraph;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import scouter.client.Images;
import scouter.client.listeners.RangeMouseListener;
import scouter.client.model.AgentColorManager;
import scouter.client.model.RefreshThread;
import scouter.client.model.RefreshThread.Refreshable;
import scouter.client.net.INetReader;
import scouter.client.net.TcpProxy;
import scouter.client.preferences.PManager;
import scouter.client.preferences.PreferenceConstants;
import scouter.client.server.Server;
import scouter.client.server.ServerManager;
import scouter.client.util.ChartUtil;
import scouter.client.util.ColorUtil;
import scouter.client.util.ConsoleProxy;
import scouter.client.util.CounterUtil;
import scouter.client.util.ExUtil;
import scouter.client.util.ImageUtil;
import scouter.client.util.MenuUtil;
import scouter.client.util.TimeUtil;
import scouter.client.util.UIUtil;
import scouter.client.views.ScouterViewPart;
import scouter.lang.TimeTypeEnum;
import scouter.lang.pack.MapPack;
import scouter.lang.value.ListValue;
import scouter.lang.value.Value;
import scouter.lang.value.ValueEnum;
import scouter.io.DataInputX;
import scouter.net.RequestCmd;
import scouter.util.CastUtil;
import scouter.util.DateUtil;
public class CounterRealTimeView extends ScouterViewPart implements Refreshable {
public static final String ID = CounterRealTimeView.class.getName();
protected String objName;
protected int objHash;
protected String objType;
protected String counter;
protected int serverId;
protected RefreshThread thread;
private IMemento memento;
IWorkbenchWindow window;
IToolBarManager man;
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
this.memento = memento;
}
public void setInput(int objHash, String objName, String objType, String counter, int serverId) throws Exception{
if (thread != null && thread.isAlive()) {
return;
}
this.objHash = objHash;
this.objName = objName;
this.objType = objType;
this.counter = counter;
this.serverId = serverId;
Server server = ServerManager.getInstance().getServer(serverId);
String svrName = "";
String counterDisplay = "";
String counterUnit = "";
if(server != null){
svrName = server.getName();
counterDisplay = server.getCounterEngine().getCounterDisplayName(objType, counter);
counterUnit = server.getCounterEngine().getCounterUnit(objType, counter);
}
if(server == null){
return;
}
desc = "ⓢ"+svrName+" | (Realtime) [" + objName + "] " + counterDisplay + (!"".equals(counterUnit)?" ("+counterUnit+")":"");
setViewTab(objType, counter, serverId);
MenuUtil.createCounterContextMenu(ID, canvas, serverId, objHash, objType, counter);
if (thread == null) {
thread = new RefreshThread(this, 2000);
thread.start();
}
thread.setName(this.toString() + " - "
+ "objHash:"+objHash
+ ", objName:"+objName
+ ", objType:"+objType
+ ", counter:"+counter
+ ", serverId:"+serverId);
}
public void getRealtimePrevPerf(int objHash, String objType, String counter) {
TcpProxy tcp = TcpProxy.getTcpProxy(serverId);
try {
MapPack param = new MapPack();
param.put("objHash", objHash);
param.put("objType", objType);
param.put("counter", counter);
long etime = TimeUtil.getCurrentTime(serverId);
long stime = etime - DateUtil.MILLIS_PER_MINUTE * 5;
param.put("stime", stime);
param.put("etime", etime);
MapPack out = (MapPack) tcp.getSingle(RequestCmd.COUNTER_PAST_TIME, param);
if (out == null){
return;
}
final ListValue time = out.getList("time");
final ListValue value = out.getList("value");
Map<Long, Value> map = new HashMap<Long, Value>();
for (int i = 0; time != null && i < time.size(); i++) {
map.put(CastUtil.clong(time.get(i)), value.get(i));
}
final TreeMap<Long, Value> treeMap = new TreeMap<Long, Value>( map );
ExUtil.exec(canvas, new Runnable() {
public void run() {
Iterator<Long> xs = treeMap.keySet().iterator();
clearAllTrace();
while(xs.hasNext()){
long tm = xs.next();
Value v = treeMap.get(tm);
if (v instanceof ListValue) {
ListValue list = (ListValue) v;
for (int j = 0, size = list.size(); j < size; j++) {
getDataProvider("data-" + j).addSample(new Sample(tm, list.getDouble(j)));
}
} else if (v != null && v.getValueType() != ValueEnum.NULL) {
getDataProvider("data").addSample(
new Sample(tm, CastUtil.cdouble(v)));
}
}
}
});
} catch (Throwable t) {
ConsoleProxy.errorSafe(t.toString());
} finally {
TcpProxy.putTcpProxy(tcp);
}
}
private boolean init = false;
boolean isActive = false;
public void refresh() {
if (init == false) {
init = true;
clearAllTrace();
getRealtimePrevPerf(objHash, objType, counter);
}
TcpProxy tcp = TcpProxy.getTcpProxy(serverId);
final Stack<Value> value = new Stack<Value>();
try {
MapPack param = new MapPack();
param.put("objHash", objHash);
param.put("counter", counter);
param.put("timetype", TimeTypeEnum.REALTIME);
isActive = false;
tcp.process(RequestCmd.COUNTER_REAL_TIME, param, new INetReader() {
public void process(DataInputX in) throws IOException {
Value v = in.readValue();
if (v != null && v.getValueType() != ValueEnum.NULL) {
value.push(v);
isActive = true;
}
}
});
} catch(Throwable t){
ConsoleProxy.errorSafe(t.toString());
} finally {
TcpProxy.putTcpProxy(tcp);
}
ExUtil.exec(canvas, new Runnable() {
public void run() {
if(isActive){
setActive();
}else{
setInactive();
}
long now = TimeUtil.getCurrentTime(serverId);
xyGraph.primaryXAxis.setRange(now - DateUtil.MILLIS_PER_MINUTE * 5, now + 1);
double maxv = 0;
if (value.size() > 0) {
Value v = value.pop();
if (v instanceof ListValue) {
ListValue list = (ListValue) v;
for (int j = 0, max = list.size(); j < max; j++) {
getDataProvider("data-" + j).addSample(new Sample(now, list.getDouble(j)));
maxv = Math.max(ChartUtil.getMax(getDataProvider("data-" + j).iterator()), maxv);
}
} else if (v.getValueType() != ValueEnum.NULL) {
getDataProvider("data").addSample(new Sample(now, CastUtil.cdouble(v)));
maxv = ChartUtil.getMax(getDataProvider("data").iterator());
}
}
if (CounterUtil.isPercentValue(objType, counter)) {
xyGraph.primaryYAxis.setRange(0, 100);
} else {
xyGraph.primaryYAxis.setRange(0, maxv);
}
canvas.redraw();
xyGraph.repaint();
}
});
}
protected XYGraph xyGraph;
protected FigureCanvas canvas;
public void createPartControl(Composite parent) {
window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
man = getViewSite().getActionBars().getToolBarManager();
man.add(new Action("Reload", ImageUtil.getImageDescriptor(Images.refresh)) {
public void run() {
init = false;
refresh();
}
});
parent.setLayout(UIUtil.formLayout(0, 0));
parent.setBackground(ColorUtil.getInstance().getColor(SWT.COLOR_WHITE));
canvas = new FigureCanvas(parent);
canvas.setScrollBarVisibility(FigureCanvas.NEVER);
canvas.setBackground(ColorUtil.getInstance().getColor(SWT.COLOR_WHITE));
canvas.setLayoutData(UIUtil.formData(0, 0, 0, 0, 100, 0, 100, 0));
canvas.addControlListener(new ControlListener() {
boolean lock = false;
public void controlResized(ControlEvent e) {
org.eclipse.swt.graphics.Rectangle r = canvas.getClientArea();
if (!lock) {
lock = true;
if (ChartUtil.isShowDescriptionAllowSize(r.height)) {
CounterRealTimeView.this.setContentDescription(desc);
} else{
CounterRealTimeView.this.setContentDescription("");
}
r = canvas.getClientArea();
lock = false;
}
xyGraph.setSize(r.width, r.height);
}
public void controlMoved(ControlEvent e) {
}
});
xyGraph = new XYGraph();
xyGraph.setShowLegend(false);
xyGraph.setShowTitle(false);
canvas.setContents(xyGraph);
xyGraph.primaryXAxis.setDateEnabled(true);
xyGraph.primaryXAxis.setShowMajorGrid(true);
xyGraph.primaryYAxis.setAutoScale(true);
xyGraph.primaryYAxis.setShowMajorGrid(true);
xyGraph.primaryXAxis.setTitle("");
xyGraph.primaryYAxis.setTitle("");
xyGraph.primaryYAxis.addMouseListener(new RangeMouseListener(getViewSite().getShell(), xyGraph.primaryYAxis));
restoreState();
canvas.addKeyListener(new KeyListener() {
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if(e.keyCode == SWT.F5){
init = false;
refresh();
}
}
});
}
protected Map<String, CircularBufferDataProvider> datas = new HashMap<String, CircularBufferDataProvider>();
private void clearAllTrace(){
Iterator<String> itr = datas.keySet().iterator();
while(itr.hasNext()){
String providerName = itr.next();
CircularBufferDataProvider provider = datas.get(providerName);
provider.clearTrace();
}
}
private CircularBufferDataProvider getDataProvider(String linename) {
CircularBufferDataProvider data = datas.get(linename);
if (data == null) {
data = new CircularBufferDataProvider(true);
datas.put(linename, data);
data.setBufferSize(155);
data.setCurrentXDataArray(new double[] {});
data.setCurrentYDataArray(new double[] {});
Trace trace = new Trace(linename, xyGraph.primaryXAxis, xyGraph.primaryYAxis, data);
trace.setPointStyle(PointStyle.NONE);
trace.getXAxis().setFormatPattern("HH:mm:ss");
trace.getYAxis().setFormatPattern("#,##0");
trace.setLineWidth(PManager.getInstance().getInt(PreferenceConstants.P_CHART_LINE_WIDTH));
trace.setTraceType(TraceType.SOLID_LINE);
trace.setTraceColor(AgentColorManager.getInstance().assignColor(objType, objHash));
xyGraph.addTrace(trace);
}
return data;
}
public void setFocus() {
statusMessage = desc + " - setInput(int objHash:"+objHash+", String objName:"+objName+", String objType:"+objType+", String counter:"+counter+", int serverId:"+serverId+")";
super.setFocus();
}
@Override
public void dispose() {
super.dispose();
if (this.thread != null) {
this.thread.shutdown();
}
}
public void saveState(IMemento memento) {
super.saveState(memento);
memento = memento.createChild(ID);
memento.putInteger("objHash", objHash);
memento.putString("objName", objName);
memento.putString("objType", objType);
memento.putString("counter", counter);
memento.putInteger("serverId", serverId);
}
private void restoreState() {
if (memento == null)
return;
IMemento m = memento.getChild(ID);
int objHash = CastUtil.cint(m.getInteger("objHash"));
String objName = m.getString("objName");
String objType = m.getString("objType");
String counter = m.getString("counter");
int serverId = CastUtil.cint(m.getInteger("serverId"));
try {
setInput(objHash, objName, objType, counter, serverId);
} catch (Exception e) {
e.printStackTrace();
}
}
}