| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.airavata.ws.monitor; |
| |
| import java.util.ArrayList; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import javax.swing.BoundedRangeModel; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import javax.swing.event.TableModelEvent; |
| import javax.swing.event.TableModelListener; |
| import javax.swing.table.TableModel; |
| |
| import org.apache.airavata.ws.monitor.MonitorUtil.EventType; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.xmlpull.infoset.XmlElement; |
| |
| public class EventDataRepository implements TableModel, BoundedRangeModel { |
| |
| /** |
| * Column |
| */ |
| public static enum Column { |
| /** |
| * TIME |
| */ |
| TIME("Time"), |
| /** |
| * ID |
| */ |
| ID("Component"), |
| /** |
| * STATUS |
| */ |
| STATUS("Status"), |
| /** |
| * MESSAGE |
| */ |
| MESSAGE("Message"); |
| |
| private String name; |
| |
| private Column(String name) { |
| this.name = name; |
| } |
| |
| /** |
| * @return The name. |
| */ |
| public String getName() { |
| return this.name; |
| } |
| } |
| |
| private static final Logger logger = LoggerFactory.getLogger(EventDataRepository.class); |
| |
| private List<TableModelListener> tableModelListeners; |
| |
| private List<ChangeListener> sliderModelListeners; |
| |
| private List<EventData> events; |
| |
| private int sliderValue; |
| |
| private boolean sliderAdjusting; |
| |
| private ChangeEvent tableModelChangeEvent; |
| |
| private EventFilter filter; |
| |
| private List<EventDataListener> monitorEventListerners; |
| |
| /** |
| * |
| * Constructs a MonitorEventData. |
| * |
| */ |
| public EventDataRepository() { |
| this(null); |
| } |
| |
| /** |
| * Constructs a NotificationTableModel. |
| */ |
| public EventDataRepository(EventFilter filter) { |
| this.filter = filter; |
| this.tableModelListeners = new LinkedList<TableModelListener>(); |
| this.sliderModelListeners = new LinkedList<ChangeListener>(); |
| this.tableModelChangeEvent = new ChangeEvent(this); // We only need one. |
| this.events = new ArrayList<EventData>(); |
| } |
| public void addEvent(XmlElement message) { |
| addEvent(new EventData(message)); |
| } |
| /** |
| * @param message |
| */ |
| public void addEvent(EventData event) { |
| // no need the check for not null because second clause is evaluated only if |
| // not null |
| if (this.filter == null || this.filter.isAcceptable(event)) { |
| boolean sliderMax = (this.sliderValue == this.events.size()); |
| |
| this.events.add(event); |
| |
| if (sliderMax) { |
| // Move the slider to the max |
| this.sliderValue = this.events.size(); |
| |
| // The new event shows up on the table only when the slider is |
| // max. |
| TableModelEvent tableEvent = new TableModelEvent(this, this.sliderValue - 1, this.sliderValue, |
| TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT); |
| fireTableChanged(tableEvent); |
| } |
| |
| // The muxmum of the slider changed regardless whether we move the |
| // slider or not. |
| fireSliderChanged(); |
| triggerListenerForMonitorEvent(event); |
| } |
| |
| } |
| public void triggerListenerForPreMonitorStart() { |
| for (EventDataListener listener : getMonitorEventListerners()) { |
| try { |
| listener.monitoringPreStart(); |
| } catch (Exception e) { |
| //just in case |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| public void triggerListenerForPostMonitorStart() { |
| for (EventDataListener listener : getMonitorEventListerners()) { |
| try { |
| listener.monitoringPostStart(); |
| } catch (Exception e) { |
| //just in case |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| public void triggerListenerForPreMonitorStop() { |
| for (EventDataListener listener : getMonitorEventListerners()) { |
| try { |
| listener.monitoringPreStop(); |
| } catch (Exception e) { |
| //just in case |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| public void triggerListenerForPostMonitorStop() { |
| for (EventDataListener listener : getMonitorEventListerners()) { |
| try { |
| listener.monitoringPostStop(); |
| } catch (Exception e) { |
| //just in case |
| e.printStackTrace(); |
| } |
| } |
| } |
| private void triggerListenerForMonitorEvent(EventData event) { |
| for (EventDataListener listener : getMonitorEventListerners()) { |
| try { |
| listener.notify(this, event); |
| if (event.getType()==EventType.WORKFLOW_TERMINATED){ |
| listener.onCompletion(event); |
| }else if (event.getType()==EventType.SENDING_FAULT){ |
| listener.onFail(event); |
| } |
| } catch (Exception e) { |
| //just in case |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| /** |
| * @return All events. |
| */ |
| public List<EventData> getEvents() { |
| return this.events; |
| } |
| |
| /** |
| * Returns a notification at a specified row. |
| * |
| * @param index |
| * The specified row. |
| * @return The notification at the specified row |
| */ |
| public EventData getEvent(int index) { |
| return this.events.get(index); |
| } |
| |
| /** |
| * @return The number of events. |
| */ |
| public int getEventSize() { |
| return this.events.size(); |
| } |
| |
| /** |
| * Clears the notifications. |
| */ |
| public void removeAllEvents() { |
| int size = this.events.size(); |
| this.events.clear(); |
| |
| this.sliderValue = 0; |
| |
| TableModelEvent event = new TableModelEvent(this, 0, Math.max(0, size - 1), TableModelEvent.ALL_COLUMNS, |
| TableModelEvent.DELETE); |
| fireTableChanged(event); |
| |
| // The muxmum of the slider changed. |
| fireSliderChanged(); |
| } |
| |
| // methods implementing TableModel interface. |
| |
| /** |
| * @see javax.swing.table.TableModel#getRowCount() |
| */ |
| public int getRowCount() { |
| // Only show the events up to the slider value. |
| return this.sliderValue; |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#getColumnCount() |
| */ |
| public int getColumnCount() { |
| return Column.values().length; |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#getColumnName(int) |
| */ |
| public String getColumnName(int columnIndex) { |
| Column[] columns = Column.values(); |
| if (columnIndex < 0 || columnIndex >= columns.length) { |
| // Should not happen. |
| throw new IllegalArgumentException("columnIndex has be be between 0 to " + columns.length); |
| } |
| return columns[columnIndex].getName(); |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#getColumnClass(int) |
| */ |
| public Class<?> getColumnClass(int columnIndex) { |
| return String.class; |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#isCellEditable(int, int) |
| */ |
| public boolean isCellEditable(int rowIndex, int columnIndex) { |
| return false; |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#getValueAt(int, int) |
| */ |
| public Object getValueAt(int rowIndex, int columnIndex) { |
| String value; |
| try { |
| EventData event = this.events.get(rowIndex); |
| value = getTextAt(event, columnIndex); |
| } catch (RuntimeException e) { |
| // This should not happen, but if it happens it blocks the UI. |
| // That's why catching it. |
| logger.error(e.getMessage(), e); |
| value = "Error"; |
| } |
| return value; |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int) |
| */ |
| public void setValueAt(Object aValue, int rowIndex, int columnIndex) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#addTableModelListener(javax.swing.event.TableModelListener) |
| */ |
| public void addTableModelListener(TableModelListener listener) { |
| this.tableModelListeners.add(listener); |
| } |
| |
| /** |
| * @see javax.swing.table.TableModel#removeTableModelListener(javax.swing.event.TableModelListener) |
| */ |
| public void removeTableModelListener(TableModelListener listener) { |
| this.tableModelListeners.remove(listener); |
| } |
| |
| // methods implementing BoundedRangeModel interface. |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#getExtent() |
| */ |
| public int getExtent() { |
| return 0; |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#setExtent(int) |
| */ |
| public void setExtent(int newExtent) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#getMaximum() |
| */ |
| public int getMaximum() { |
| return getEventSize(); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#setMaximum(int) |
| */ |
| public void setMaximum(int newMaximum) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#getMinimum() |
| */ |
| public int getMinimum() { |
| return 0; |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#setMinimum(int) |
| */ |
| public void setMinimum(int newMinimum) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#getValue() |
| */ |
| public int getValue() { |
| return this.sliderValue; |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#setValue(int) |
| */ |
| public void setValue(int newValue) { |
| if (this.sliderValue == newValue) { |
| return; |
| } |
| |
| // Correct the value to be withing the range. |
| if (newValue < 0) { |
| newValue = 0; |
| } |
| if (newValue > this.events.size()) { |
| newValue = this.events.size(); |
| } |
| |
| int oldRowCount = this.sliderValue; |
| this.sliderValue = newValue; |
| |
| TableModelEvent event; |
| if (oldRowCount < this.sliderValue) { |
| event = new TableModelEvent(this, oldRowCount, this.sliderValue, TableModelEvent.ALL_COLUMNS, |
| TableModelEvent.INSERT); |
| } else { |
| event = new TableModelEvent(this, this.sliderValue, oldRowCount, TableModelEvent.ALL_COLUMNS, |
| TableModelEvent.DELETE); |
| } |
| fireTableChanged(event); |
| fireSliderChanged(); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#getValueIsAdjusting() |
| */ |
| public boolean getValueIsAdjusting() { |
| return this.sliderAdjusting; |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#setValueIsAdjusting(boolean) |
| */ |
| public void setValueIsAdjusting(boolean adjusting) { |
| this.sliderAdjusting = adjusting; |
| fireSliderChanged(); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#setRangeProperties(int, int, int, int, boolean) |
| */ |
| public void setRangeProperties(int value, int extent, int min, int max, boolean adjusting) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#addChangeListener(javax.swing.event.ChangeListener) |
| */ |
| public void addChangeListener(ChangeListener listener) { |
| this.sliderModelListeners.add(listener); |
| } |
| |
| /** |
| * @see javax.swing.BoundedRangeModel#removeChangeListener(javax.swing.event.ChangeListener) |
| */ |
| public void removeChangeListener(ChangeListener listener) { |
| this.sliderModelListeners.remove(listener); |
| } |
| |
| private String getTextAt(EventData event, int columnIndex) { |
| Column[] columns = Column.values(); |
| if (columnIndex < 0 || columnIndex >= columns.length) { |
| // Should not happen. |
| throw new IllegalArgumentException("columnIndex has be be between 0 to " + columns.length); |
| } |
| Column column = columns[columnIndex]; |
| String value; |
| switch (column) { |
| case TIME: |
| value = event.getTimeText(); |
| break; |
| case ID: |
| value = event.getIDText(); |
| break; |
| case STATUS: |
| value = event.getStatusText(); |
| break; |
| case MESSAGE: |
| value = event.getMessage(); |
| break; |
| default: |
| // Should not happen. |
| throw new IllegalArgumentException("columnIndex has be be between 0 to " + columns.length); |
| } |
| return value; |
| } |
| |
| private void fireTableChanged(TableModelEvent event) { |
| for (TableModelListener listener : this.tableModelListeners) { |
| listener.tableChanged(event); |
| } |
| } |
| |
| private void fireSliderChanged() { |
| for (ChangeListener listener : this.sliderModelListeners) { |
| listener.stateChanged(this.tableModelChangeEvent); |
| } |
| } |
| private List<EventDataListener> getMonitorEventListerners() { |
| if (monitorEventListerners==null){ |
| monitorEventListerners=new ArrayList<EventDataListener>(); |
| } |
| return monitorEventListerners; |
| } |
| |
| public void registerEventListener(EventDataListener listener){ |
| if (listener!=null) { |
| getMonitorEventListerners().add(listener); |
| } |
| } |
| |
| public void unregisterEventListener(EventDataListener listener){ |
| if (getMonitorEventListerners().contains(listener)) { |
| getMonitorEventListerners().remove(listener); |
| } |
| } |
| } |