/*
* Copyright 2005 by Oracle USA
* 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A.
* All rights reserved.
*/
package javax.ide.editor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ide.model.Document;
import javax.ide.Service;
import javax.ide.spi.ProviderNotFoundException;
import javax.ide.command.Context;
import javax.ide.editor.spi.EditorHook;
import javax.ide.extension.ExtensionRegistry;
import javax.ide.util.MetaClass;
/**
* The EditorManager
manages the life cycle of {@link Editor}s.
* It is also the registry of information about what editors can be used with
* particular documents.
* * Clients use this class to open an editor on a {@link javax.ide.model.Document}. * When clients request to open an editor on a specific document, the editor * manager performs the following tasks:
* *
*
*
*
* *
*
*
*
* IDE service providers must provide a concrete implementation of this class.
*/
public abstract class EditorManager extends Service
{
/**
* Map of String:List. Keys are ids of editor types, values are lists of
* EditorListener.
*/
private final Map _listenerMap = new HashMap();
private boolean _initializedHookListeners = false;
/**
* Returns the Editor that is currently active.
*
* @return the currently active editor, or null if no editor is currently
* active.
*/
public abstract Editor getActiveEditor();
/**
* Returns all currently open editors.
*
* @return a set of Editor instances for all currently open editors. Must not
* return null, may return an empty collection. The collection is immutable.
*/
public abstract Set /*
*
* If the document is already open using that editor, the editor will be
* made active.
*
* @param context the context to open an editor for. Must not be null.
* @param typeID the id of an editor type to open the context document in. If
* null, the IDE will open the document with the default editor.
* @return the editor that was opened or activated.
* @throws UnsupportedOperationException when the document cannot be
* opened by any editor.
*/
public abstract Editor openEditor( Context context, String typeID );
/**
* Close the specified {@link Editor}.
*
* @param editor The editor to be closed. Must not be null.
*/
public abstract void closeEditor( Editor editor );
/**
* Add an {@link EditorListener}.
*
* @param listener the {@link EditorListener} to add. Must not be null.
* @param editorClass Only events for this class of editor will be dispatched
* to the specified listener. May be null, indicating that all editor events
* will be dispatched.
*/
public final void addEditorListener( EditorListener listener,
String editorClass )
{
if ( listener == null )
{
throw new NullPointerException( "listener is null" );
}
if ( editorClass == null )
{
editorClass = EditorHook.ANY_EDITOR_CLASS;
}
List listeners = (List) _listenerMap.get( editorClass );
if ( listeners == null )
{
listeners = new ArrayList();
_listenerMap.put( editorClass, listeners );
}
listeners.add( listener );
}
/**
* Remove an {@link EditorListener}.
*
* @param l The {@link EditorListener} to remove.
* @param editorClass The class of editors from which listener should be
* removed. May be null, indicating that all editor events
* will be dispatched.
*/
public final void removeEditorListener( EditorListener l,
String editorClass )
{
if ( editorClass == null )
{
editorClass = EditorHook.ANY_EDITOR_CLASS;
}
List listeners = (List) _listenerMap.get( editorClass );
if ( listeners != null )
{
listeners.remove( l );
}
else
{
throw new IllegalArgumentException(
"No listeners are registered for editor type "+editorClass
);
}
}
private final Collection getListeners( Editor editor )
{
initializeHookListeners();
List listeners = (List) _listenerMap.get( editor.getClass().getName() );
List allListeners = (List) _listenerMap.get( EditorHook.ANY_EDITOR_CLASS );
List fullList = new ArrayList();
if ( listeners != null )
{
fullList.addAll( listeners );
}
if ( allListeners != null )
{
fullList.addAll( allListeners );
}
return fullList;
}
/**
* Notifies all editor listeners that the specified editor was
* opened.
*
* @param editor the editor which was opened.
*/
protected final void fireEditorOpened( Editor editor )
{
Collection listeners = getListeners( editor );
if ( !listeners.isEmpty() )
{
EditorEvent event = new EditorEvent( editor );
for ( Iterator i = listeners.iterator(); i.hasNext(); )
{
((EditorListener)i.next()).opened( event );
}
}
}
/**
* Notifies all editor listeners that the specified editor was
* closed.
*
* @param editor the editor which was closed.
*/
protected final void fireEditorClosed( Editor editor )
{
Collection listeners = getListeners( editor );
if ( !listeners.isEmpty() )
{
EditorEvent event = new EditorEvent( editor );
for ( Iterator i = listeners.iterator(); i.hasNext(); )
{
((EditorListener)i.next()).closed( event );
}
}
}
/**
* Notifies all editor listeners that the specified editor was
* activated.
*
* @param editor the editor which was activated.
*/
protected final void fireEditorActivated( Editor editor )
{
Collection listeners = getListeners( editor );
if ( !listeners.isEmpty() )
{
EditorEvent event = new EditorEvent( editor );
for ( Iterator i = listeners.iterator(); i.hasNext(); )
{
((EditorListener)i.next()).activated( event );
}
}
}
/**
* Notifies all editor listeners that the specified editor was
* deactivated.
*
* @param editor the editor which was deactivated.
*/
protected final void fireEditorDeactivated( Editor editor )
{
Collection listeners = getListeners( editor );
if ( !listeners.isEmpty() )
{
EditorEvent event = new EditorEvent( editor );
for ( Iterator i = listeners.iterator(); i.hasNext(); )
{
((EditorListener)i.next()).deactivated( event );
}
}
}
private void initializeHookListeners()
{
if ( !_initializedHookListeners )
{
try
{
EditorHook editorHook =
(EditorHook) ExtensionRegistry.getExtensionRegistry().getHook( EditorHook.ELEMENT );
Map listeners = editorHook.getListeners();
for ( Iterator i = listeners.keySet().iterator(); i.hasNext(); )
{
String key = (String) i.next();
Collection listenerClasses = (Collection) listeners.get( key );
for ( Iterator j = listenerClasses.iterator(); j.hasNext(); )
{
MetaClass thisClass = (MetaClass) j.next();
try
{
EditorListener el = (EditorListener) thisClass.newInstance();
addEditorListener( el, key );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
}
}
finally
{
_initializedHookListeners = true;
}
}
}
/**
* Get the editor manager implementation for this IDE.
*
* @return the editor manager implementation.
*/
public static EditorManager getEditorManager()
{
try
{
return (EditorManager) getService( EditorManager.class );
}
catch ( ProviderNotFoundException nse )
{
nse.printStackTrace();
throw new IllegalStateException( "No editor manager." );
}
}
}
type
is null, the IDE will open the
* document with the most appropriate editor.