Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: javax/ide/editor/EditorManager.java


1   package javax.ide.editor;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.HashMap;
6   import java.util.Iterator;
7   import java.util.List;
8   import java.util.Map;
9   
10  import javax.ide.Service;
11  import javax.ide.spi.ProviderNotFoundException;
12  import javax.ide.command.Context;
13  import javax.ide.editor.spi.EditorHook;
14  import javax.ide.extension.ExtensionRegistry;
15  import javax.ide.util.MetaClass;
16  
17  /**
18   * The <code>EditorManager</code> manages the life cycle of {@link Editor}s.
19   * It is also the registry of information about what editors can be used with
20   * particular documents.<p>
21   *
22   * Clients use this class to open an editor on a {@link javax.ide.model.Document}.  
23   * When clients request to open an editor on a specific document, the editor 
24   * manager performs the following tasks:<p>
25   *
26   * <ul>
27   *    <li>1. Create an instance of the requested editor type. If no type is
28   *    specified, create an instance of the preferred editor associated with
29   *    the target document.</li><p>
30   *    <li>2. Call the {@link Editor#open} method passing the appropriate
31   *    context.</li><p>
32   *    <li>3. Call the {@link Editor#restore} method to restore any previously
33   *    saved editor state.</li><p>
34   *    <li>5. Call the {@link javax.ide.view.View#setVisible} method to display 
35   *    the editor.
36   *    <li>4. Fire the {@link EditorListener#opened} event.
37   * </ul>
38   *
39   * Similarly, the editor manager {@link #closeEditor} method should be called
40   * by clients to request closing an editor. When closing an editor the 
41   * editor manager performs the following tasks:<p>
42   *
43   * <ul>
44   *    <li>3. Call the {@link Editor#save} method to save the editor 
45   *    current state.</li><p>
46   *    <li>1. Call the {@link Editor#close} method.</li><p>
47   *    <li>4. Fire the {@link EditorListener#closed} event.
48   * </ul>
49   *
50   * Extensions that need to know when editors are opened, closed, activated, 
51   * and/or deactivated can add {@link EditorListener}s to the editor manager.
52   * Listener implementations are declared in the <b>editor-listener</b> 
53   * section of the extension manifest.<p>
54   *
55   * IDE service providers must provide a concrete implementation of this class.
56   */
57  public abstract class EditorManager extends Service
58  {
59    /**
60     * Map of String:List. Keys are ids of editor types, values are lists of 
61     * EditorListener.
62     */
63    private final Map _listenerMap = new HashMap();
64    private boolean _initializedHookListeners = false;
65  
66    /**
67     * Returns the Editor that is currently active.
68     * 
69     * @return the currently active editor.
70     */
71    public abstract Editor getActiveEditor();
72  
73    /**
74     * Opens a document in the editor identified by the given editor
75     * type identifier.  If <code>type</code> is null, the IDE will open the 
76     * document with the most appropriate editor.<p>
77     *
78     * If the document is already open using that editor, the editor will be
79     * made active.
80     *
81     * @param context the context to open an editor for.
82     * @param typeID the id of an editor type to open the context document in. If
83     *    null, the IDE will open the document with the default editor.
84     * @return the editor that was opened or activated.
85     * @throws UnsupportedOperationException when the document cannot be 
86     *    opened by any editor.
87     */
88    public abstract Editor openEditor( Context context, String typeID );
89  
90    /**
91     * Close the specified {@link Editor}.
92     *
93     * @param editor The editor to be closed.
94     */
95    public abstract void closeEditor( Editor editor );
96  
97    /**
98     * Add an {@link EditorListener}.
99     *
100    * @param listener the {@link EditorListener} to add.
101    * @param editorClass Only events for this class of editor will be dispatched
102    *  to the specified listener. May be null, indicating that all editor events
103    *  will be dispatched.
104    */
105   public final void addEditorListener( EditorListener listener, 
106     String editorClass )
107   {
108     if ( editorClass == null )
109     {
110       editorClass = EditorHook.ANY_EDITOR_CLASS;
111     }
112     List listeners = (List) _listenerMap.get( editorClass );
113     if ( listeners == null )
114     {
115       listeners = new ArrayList();
116       _listenerMap.put( editorClass, listeners );
117     }
118     listeners.add( listener );
119   }
120 
121   /**
122    * Remove an {@link EditorListener}.
123    *
124    * @param l The {@link EditorListener} to remove. 
125    * @param editorClass The class of editors from which listener should be
126    *  removed.  May be null, indicating that all editor events
127    *  will be dispatched.
128    */
129   public final void removeEditorListener( EditorListener l, 
130     String editorClass )
131   {
132     if ( editorClass == null )
133     {
134       editorClass = EditorHook.ANY_EDITOR_CLASS;
135     }  
136     List listeners = (List) _listenerMap.get( editorClass );
137     if ( listeners != null )
138     {
139       listeners.remove( l );
140     }
141     else
142     {
143       throw new IllegalArgumentException( 
144         "No listeners are registered for editor type "+editorClass      
145       );
146     }
147   }
148   
149   private final Collection getListeners( Editor editor )
150   {
151     initializeHookListeners();  
152     List listeners = (List) _listenerMap.get( editor.getClass().getName() );
153     List allListeners = (List) _listenerMap.get( EditorHook.ANY_EDITOR_CLASS );
154     List fullList = new ArrayList();
155     if ( listeners != null )
156     {
157       fullList.addAll( listeners );
158     }
159     if ( allListeners != null )
160     {
161       fullList.addAll( allListeners );
162     }
163     
164     return fullList;
165   }
166   
167   /**
168    * Notifies all editor listeners that the specified editor was
169    * opened.
170    * 
171    * @param editor the editor which was opened.
172    */
173   protected final void fireEditorOpened( Editor editor )
174   {
175     Collection listeners = getListeners( editor );
176     
177     if ( !listeners.isEmpty() )
178     {
179       EditorEvent event = new EditorEvent( editor );
180       for ( Iterator i = listeners.iterator(); i.hasNext(); )
181       {
182         ((EditorListener)i.next()).opened( event );
183       }
184     }    
185   }
186   
187   /**
188    * Notifies all editor listeners that the specified editor was
189    * closed.
190    * 
191    * @param editor the editor which was closed.
192    */
193   protected final void fireEditorClosed( Editor editor )
194   {
195     Collection listeners = getListeners( editor );
196     
197     if ( !listeners.isEmpty() )
198     {
199       EditorEvent event = new EditorEvent( editor );
200       for ( Iterator i = listeners.iterator(); i.hasNext(); )
201       {
202         ((EditorListener)i.next()).closed( event );
203       }
204     }
205   }  
206   
207   /**
208    * Notifies all editor listeners that the specified editor was
209    * activated.
210    * 
211    * @param editor the editor which was activated.
212    */
213   protected final void fireEditorActivated( Editor editor )
214   {
215     Collection listeners = getListeners( editor );
216 
217     if ( !listeners.isEmpty() )
218     {
219       EditorEvent event = new EditorEvent( editor );
220       for ( Iterator i = listeners.iterator(); i.hasNext(); )
221       {
222         ((EditorListener)i.next()).activated( event );
223       }
224     }
225   }    
226   
227   /**
228    * Notifies all editor listeners that the specified editor was
229    * deactivated.
230    * 
231    * @param editor the editor which was deactivated.
232    */
233   protected final void fireEditorDeactivated( Editor editor )
234   {
235     Collection listeners = getListeners( editor );
236 
237     if ( !listeners.isEmpty() )
238     {
239       EditorEvent event = new EditorEvent( editor );
240       for ( Iterator i = listeners.iterator(); i.hasNext(); )
241       {
242         ((EditorListener)i.next()).deactivated( event );
243       }
244     }
245   }   
246 
247   private void initializeHookListeners()
248   {
249     if ( !_initializedHookListeners )
250     {
251       try
252       {
253         EditorHook editorHook = 
254           (EditorHook) ExtensionRegistry.getExtensionRegistry().getHook( EditorHook.ELEMENT );
255       
256         Map listeners = editorHook.getListeners();
257         for ( Iterator i = listeners.keySet().iterator(); i.hasNext(); )
258         {
259           String key = (String) i.next();
260           Collection listenerClasses = (Collection) listeners.get( key );
261           for ( Iterator j = listenerClasses.iterator(); j.hasNext(); )
262           {
263             MetaClass thisClass = (MetaClass) j.next();
264             try
265             {
266               EditorListener el = (EditorListener) thisClass.newInstance();
267               addEditorListener( el, key );
268             }
269             catch ( Exception e )
270             {
271               e.printStackTrace();
272             }
273           }
274         }
275       }
276       finally
277       {
278         _initializedHookListeners = true;
279       }
280     }
281   }
282   
283   /**
284    * Get the editor manager implementation for this IDE.
285    * 
286    * @return the editor manager implementation.
287    */
288   public static EditorManager getEditorManager()
289   {
290     try
291     {
292       return (EditorManager) getService( EditorManager.class );      
293     }
294     catch ( ProviderNotFoundException nse )
295     {
296       nse.printStackTrace();
297       throw new IllegalStateException( "No editor manager." );
298     }
299   }
300   
301   
302 }