/*
* Copyright 2005 by Oracle USA
* 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A.
* All rights reserved.
*/
package javax.ide.command;
import javax.ide.menu.IDEAction;
import javax.ide.util.MetaClass;
/**
* Controllers encapulate extension defined {@link UpdateHandler}s and
* {@link InvokeHandler}s. Generally, {@link javax.ide.view.View}s use
* controllers to check whether a context sensitive command can be
* executed given the current context, and to do the actual execution of
* that command.
*/
public final class Controller
{
private MetaClass _updateClass;
private MetaClass _invokeClass;
private final boolean _isContextSensitive;
private UpdateHandler _updateHandler;
private InvokeHandler _invokeHandler;
private static UpdateHandler _nullUpdateHandler;
private static InvokeHandler _nullInvokeHandler;
/**
* Constructs a controller object, deferring class loading and instantiation
* of its invoke and update handler objects until needed. Generally, this is
* only used by IDE implementations when loading controllers from the manifest
* file.
*
* @param invokeHandlerClass a metaclass of an InvokeHandler.
* @param updateHandlerClass a metaclass of an UpdateHandler. May
* be null.
*/
public Controller( MetaClass invokeHandlerClass,
MetaClass updateHandlerClass )
{
if ( invokeHandlerClass == null )
{
throw new NullPointerException( "invokeHandlerClass is null" );
}
_isContextSensitive = updateHandlerClass == null;
_updateClass = updateHandlerClass;
_invokeClass = invokeHandlerClass;
}
/**
* Constructs a controller object.
*
* @param invokeHandler the invocation handler. Must not be null.
* @param updateHandler the update handler. May be null for actions which
* are always enabled.
*/
public Controller( InvokeHandler invokeHandler, UpdateHandler updateHandler )
{
if ( _invokeHandler == null )
{
throw new NullPointerException( "invokeHandler is null" );
}
_isContextSensitive = _updateHandler == null;
_invokeHandler = invokeHandler;
_updateHandler = updateHandler;
}
/**
* Get the invoke handler for this controller.
*
* @return the invoke handler for this controller. Will never return null.
*/
public InvokeHandler getInvokeHandler()
{
if ( _invokeHandler == null )
{
try
{
_invokeHandler = (InvokeHandler) _invokeClass.newInstance();
}
catch ( Exception e )
{
e.printStackTrace();
// TODO report error.
_nullInvokeHandler = new NullInvokeHandler();
_invokeHandler = _nullInvokeHandler;
}
}
return _invokeHandler;
}
/**
* Get the update handler for this controller.
*
* @return the update handler for this controller. If the action is always
* enabled, returns a handler that always sets the action enabled. Will
* never return null.
*/
public UpdateHandler getUpdateHandler()
{
if ( _updateHandler == null && _updateClass != null )
{
try
{
_updateHandler = (UpdateHandler) _updateClass.newInstance();
}
catch ( Exception e )
{
e.printStackTrace();
// TODO error handling.
}
}
if ( _updateHandler == null )
{
// Either _updateClass == null or an exception occurred creating the
// update class.
if ( _nullUpdateHandler == null )
{
_nullUpdateHandler = new NullUpdateHandler();
}
_updateHandler = _nullUpdateHandler;
}
return _updateHandler;
}
/**
* Get whether this controller is context sensitive. A context sensitive
* controller has an associated UpdateHandler that adjusts the
* action based on the context.
*
* @return true if the UpdateHandler associated with this
* Controller may change the state of the action based on the
* context.
*/
public boolean isContextSensitive()
{
return _isContextSensitive;
}
private static final class NullInvokeHandler implements InvokeHandler
{
public boolean invoke( IDEAction action, Context context )
{
return true;
}
}
private static final class NullUpdateHandler implements UpdateHandler
{
public boolean update( IDEAction action, Context context )
{
action.setEnabled( true );
return true;
}
}
}