/*
* (c) Rob Gordon 2005
*/
package org.oddjob.monitor.model;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Observable;
import org.oddjob.Stateful;
import org.oddjob.framework.JobDestroyedException;
import org.oddjob.framework.PropertyChangeNotifier;
import org.oddjob.logging.ConsoleArchiver;
import org.oddjob.logging.LogArchiver;
import org.oddjob.logging.LogLevel;
import org.oddjob.monitor.context.ExplorerContext;
import org.oddjob.state.StateEvent;
import org.oddjob.state.StateListener;
/**
* Model for controlling the detail views.
*
* @author rob
*
*/
public class DetailModel implements PropertyChangeNotifier {
public static final String SELECTED_CONTEXT_PROPERTY = "selectedContext";
public static final String TAB_SELECTED_PROPERTY = "tabSelected";
public static final int STATE_TAB = 0;
public static final int CONSOLE_TAB = 1;
public static final int LOG_TAB = 2;
public static final int PROPERTIES_TAB = 3;
/** Tab selected */
private int tabSelected = STATE_TAB;
/** The selected Job */
private ExplorerContext selectedContext;
/** Console model */
private final LogModel consoleModel = new LogModel();
/** Log model */
private final LogModel logModel = new LogModel();
/** Property model */
private PropertyModel propertyModel = new PropertyModel();
/** State model */
private final StateModel stateModel = new StateModel();
/** State control */
private final StateListener stateListener = new StateListener() {
public void jobStateChange(StateEvent event) {
stateModel.change(event);
}
};
private final PropertyChangeSupport propertySupport =
new PropertyChangeSupport(this);
/**
* Get the model for the Console panel.
*
* @return The LogModel for the console.
*/
public LogModel getConsoleModel() {
return consoleModel;
}
/**
* Get the model for the Log panel.
*
* @return The LogModel for the log;
*/
public LogModel getLogModel() {
return logModel;
}
/**
* Get the model for the Property panel.
*
* @return The PropertyModel.
*/
public PropertyModel getPropertyModel() {
return propertyModel;
}
/**
* Set currently selected tab.
*
* @param tabSelected The tab number.
*/
public void setTabSelected(int tabSelected) {
if (this.tabSelected == tabSelected) {
return;
}
if (selectedContext != null) {
freeTab(this.tabSelected);
}
PropertyChangeEvent event = new PropertyChangeEvent(
this, TAB_SELECTED_PROPERTY,
new Integer(this.tabSelected), new Integer(tabSelected));
this.tabSelected = tabSelected;
if (selectedContext != null) {
try {
engageTab(tabSelected);
} catch (JobDestroyedException e) {
// This is highly unlikely. An can only be caused if a user clicks a tab
// of a destroyed job before the job tree has caught up with structural
// changes.
}
}
propertySupport.firePropertyChange(event);
}
/**
* Get the selected detail tab.
*
* @return The selected tab.
*/
public int getTabSelected() {
return tabSelected;
}
private void freeTab(int index) {
Object selectedJob = selectedContext.getThisComponent();
switch (index) {
case STATE_TAB:
// state
stateModel.clear();
if (selectedJob instanceof Stateful) {
((Stateful) selectedJob).removeStateListener(stateListener);
}
break;
case CONSOLE_TAB:
// console
ConsoleArchiver consoleArchiver =
(ConsoleArchiver) selectedContext.getValue(LogContextInialiser.CONSOLE_ARCHIVER);
consoleArchiver.removeConsoleListener(consoleModel, selectedJob);
consoleModel.setClear();
break;
case LOG_TAB:
// logger
LogArchiver logArchiver =
(LogArchiver) selectedContext.getValue(LogContextInialiser.LOG_ARCHIVER);
logArchiver.removeLogListener(logModel, selectedJob);
logModel.setClear();
break;
case PROPERTIES_TAB:
break;
default:
throw new IllegalArgumentException("Index " + index + " > 3.");
}
}
private void engageTab(int index) throws JobDestroyedException {
Object selectedJob = selectedContext.getThisComponent();
switch (index) {
case STATE_TAB:
// stateful
if (selectedJob instanceof Stateful) {
((Stateful) selectedJob).addStateListener(stateListener);
}
break;
case CONSOLE_TAB:
ConsoleArchiver consoleArchiver =
(ConsoleArchiver) selectedContext.getValue(LogContextInialiser.CONSOLE_ARCHIVER);
consoleArchiver.addConsoleListener(consoleModel, selectedJob, -1, 1000);
break;
case LOG_TAB:
// add logging pane
LogArchiver logArchiver =
(LogArchiver) selectedContext.getValue(LogContextInialiser.LOG_ARCHIVER);
logArchiver.addLogListener(logModel, selectedJob, LogLevel.TRACE, -1, 1000);
break;
case PROPERTIES_TAB:
break;
default:
throw new IllegalArgumentException("Index " + index + " > 3.");
}
}
public void setSelectedContext(ExplorerContext newContext) {
if (selectedContext == newContext) {
return;
}
if (selectedContext != null) {
freeTab(tabSelected);
}
ExplorerContext oldContext = selectedContext;
selectedContext = newContext;
if (selectedContext != null) {
try {
engageTab(tabSelected);
} catch (JobDestroyedException e) {
// Caused when the window event thread is behind
// The structural changes.
selectedContext = null;
}
}
PropertyChangeEvent event = new PropertyChangeEvent(
this, SELECTED_CONTEXT_PROPERTY, oldContext, selectedContext);
propertySupport.firePropertyChange(event);
}
/**
* Get the selected job.
*
* @return The selected job or null if none is.
*/
public Object getSelectedJob() {
if (selectedContext == null) {
return null;
}
return selectedContext.getThisComponent();
}
/**
* Get the state model.
*
* @return The StateModel.
*/
public Observable getStateModel() {
return stateModel;
}
public void addPropertyChangeListener(
PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(
PropertyChangeListener listener) {
propertySupport.removePropertyChangeListener(listener);
}
}