src/core/net/sf/basedb/util/extensions/ExtensionsInvoker.java

Code
Comments
Other
Rev Date Author Line
4158 22 Feb 08 nicklas 1 /**
4207 04 Apr 08 nicklas 2   $Id:ExtensionsInvoker.java 4187 2008-03-20 11:15:25Z nicklas $
4158 22 Feb 08 nicklas 3
4158 22 Feb 08 nicklas 4   Copyright (C) Authors contributing to this file.
4158 22 Feb 08 nicklas 5
4158 22 Feb 08 nicklas 6   This file is part of BASE - BioArray Software Environment.
4158 22 Feb 08 nicklas 7   Available at http://base.thep.lu.se/
4158 22 Feb 08 nicklas 8
4158 22 Feb 08 nicklas 9   BASE is free software; you can redistribute it and/or
4158 22 Feb 08 nicklas 10   modify it under the terms of the GNU General Public License
4479 05 Sep 08 jari 11   as published by the Free Software Foundation; either version 3
4158 22 Feb 08 nicklas 12   of the License, or (at your option) any later version.
4158 22 Feb 08 nicklas 13
4158 22 Feb 08 nicklas 14   BASE is distributed in the hope that it will be useful,
4158 22 Feb 08 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
4158 22 Feb 08 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4158 22 Feb 08 nicklas 17   GNU General Public License for more details.
4158 22 Feb 08 nicklas 18
4158 22 Feb 08 nicklas 19   You should have received a copy of the GNU General Public License
4515 11 Sep 08 jari 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
4158 22 Feb 08 nicklas 21 */
4158 22 Feb 08 nicklas 22 package net.sf.basedb.util.extensions;
4158 22 Feb 08 nicklas 23
4158 22 Feb 08 nicklas 24 import java.util.Collection;
5598 30 Mar 11 nicklas 25 import java.util.Iterator;
4158 22 Feb 08 nicklas 26
7272 19 Jan 17 nicklas 27 import net.sf.basedb.util.extensions.events.EventType;
7272 19 Jan 17 nicklas 28
4158 22 Feb 08 nicklas 29 /**
4163 28 Feb 08 nicklas 30   Object of this class handles a single invokation of the extensions
4170 07 Mar 08 nicklas 31   for one or several extension points. Call 
4207 04 Apr 08 nicklas 32   {@link Registry#useExtensions(ClientContext, ExtensionsFilter, String...)}
4163 28 Feb 08 nicklas 33   to create an invoker object. With this object you can
4163 28 Feb 08 nicklas 34   {@link #iterate()} over all actions created by the extensions, or
4163 28 Feb 08 nicklas 35   use one of the render methods to render all actions automatically.
4158 22 Feb 08 nicklas 36
4163 28 Feb 08 nicklas 37   <p>
4163 28 Feb 08 nicklas 38   The {@link #renderDefault()} method uses the default render objects 
4163 28 Feb 08 nicklas 39   registered with the extension points and/or extensions (see 
4163 28 Feb 08 nicklas 40   {@link ExtensionPoint#getRendererFactory()} and {@link Extension#getRendererFactory()}).
4163 28 Feb 08 nicklas 41   Since the registration of rendering factories are optional, the
4163 28 Feb 08 nicklas 42   <code>renderDefault()</code> method only works with extensions that have
4170 07 Mar 08 nicklas 43   done so. If an action can't be associated with a renderer, an exception
4170 07 Mar 08 nicklas 44   is thrown.
4163 28 Feb 08 nicklas 45
4163 28 Feb 08 nicklas 46   <p>
4163 28 Feb 08 nicklas 47   If there is no default rendering factory or if you want to override the default
4170 07 Mar 08 nicklas 48   renderer, you can use the {@link #render(Renderer)} method. This will force
4170 07 Mar 08 nicklas 49   the use of the specified renderer for all extensions, ignoring all renderers
4170 07 Mar 08 nicklas 50   set by extension points or extensions.
4163 28 Feb 08 nicklas 51
4158 22 Feb 08 nicklas 52   @author nicklas
4158 22 Feb 08 nicklas 53   @version 2.7
4207 04 Apr 08 nicklas 54   @base.modified $Date:2008-03-20 12:15:25 +0100 (Thu, 20 Mar 2008) $
4163 28 Feb 08 nicklas 55 */
4163 28 Feb 08 nicklas 56 public class ExtensionsInvoker<A extends Action>
5598 30 Mar 11 nicklas 57   implements Iterable<A>
4158 22 Feb 08 nicklas 58 {
4158 22 Feb 08 nicklas 59
8083 20 Oct 22 nicklas 60   private final ClientContext clientContext;
5486 12 Nov 10 nicklas 61   private final Collection<ExtensionContext<A>> contexts;
4618 30 Oct 08 nicklas 62   private boolean clearErrors;
4158 22 Feb 08 nicklas 63   
4170 07 Mar 08 nicklas 64   /**
4170 07 Mar 08 nicklas 65     Creates a new invoker object.
4170 07 Mar 08 nicklas 66   */
8083 20 Oct 22 nicklas 67   ExtensionsInvoker(ClientContext clientContext, Collection<ExtensionContext<A>> contexts)
4158 22 Feb 08 nicklas 68   {
8083 20 Oct 22 nicklas 69     this.clientContext = clientContext;
4207 04 Apr 08 nicklas 70     this.contexts = contexts;
4158 22 Feb 08 nicklas 71   }
4158 22 Feb 08 nicklas 72   
4163 28 Feb 08 nicklas 73   /**
8083 20 Oct 22 nicklas 74     Get the client context that is used by this invoker.
8083 20 Oct 22 nicklas 75     @since 3.19.4
8083 20 Oct 22 nicklas 76   */
8083 20 Oct 22 nicklas 77   public ClientContext getClientContext()
8083 20 Oct 22 nicklas 78   {
8083 20 Oct 22 nicklas 79     return clientContext;
8083 20 Oct 22 nicklas 80   }
8083 20 Oct 22 nicklas 81   
8083 20 Oct 22 nicklas 82   /**
4618 30 Oct 08 nicklas 83     Set a flag to indicate if existing errors should be cleared 
4618 30 Oct 08 nicklas 84     before an action is rendered. If this setting is not enabled (default)
4618 30 Oct 08 nicklas 85     old errors are never cleared.
4618 30 Oct 08 nicklas 86     @param clearErrors TRUE to clear old errors, FALSE to keep them
4618 30 Oct 08 nicklas 87     @since 2.9
4618 30 Oct 08 nicklas 88   */
4618 30 Oct 08 nicklas 89   public void setClearErrors(boolean clearErrors)
4618 30 Oct 08 nicklas 90   {
4618 30 Oct 08 nicklas 91     this.clearErrors = clearErrors;
4618 30 Oct 08 nicklas 92   }
4618 30 Oct 08 nicklas 93
4618 30 Oct 08 nicklas 94   /**
4908 28 Apr 09 nicklas 95     Get the number of enabled extensions in this invokation.
4908 28 Apr 09 nicklas 96     Note that this number doesn't have to correspond to the actual
4908 28 Apr 09 nicklas 97     number of actions since an extension may choose to create 0, 1 or
4908 28 Apr 09 nicklas 98     more actions.
4908 28 Apr 09 nicklas 99     @return The number of enabled extensions
4908 28 Apr 09 nicklas 100     @since 2.12
4908 28 Apr 09 nicklas 101   */
4908 28 Apr 09 nicklas 102   public int getNumExtensions()
4908 28 Apr 09 nicklas 103   {
4908 28 Apr 09 nicklas 104     return contexts.size();
4908 28 Apr 09 nicklas 105   }
4908 28 Apr 09 nicklas 106   
4908 28 Apr 09 nicklas 107   /**
4163 28 Feb 08 nicklas 108     Create an iterator that iterates over all {@link Action}:s created
4163 28 Feb 08 nicklas 109     by the extensions. The iterator may return zero actions if none
4163 28 Feb 08 nicklas 110     has been created. 
4163 28 Feb 08 nicklas 111     @return An iterator
4163 28 Feb 08 nicklas 112   */
4168 04 Mar 08 nicklas 113   public ActionIterator<A> iterate()
4158 22 Feb 08 nicklas 114   {
4207 04 Apr 08 nicklas 115     return new ActionIterator<A>(contexts.iterator());
4158 22 Feb 08 nicklas 116   }
4158 22 Feb 08 nicklas 117   
4163 28 Feb 08 nicklas 118   /**
4163 28 Feb 08 nicklas 119     Render all actions using the renderers created by the
4870 01 Apr 09 nicklas 120     default renderer factories as specified by the registered 
4163 28 Feb 08 nicklas 121     extension points and/or extensions.
4163 28 Feb 08 nicklas 122     @see ExtensionPoint#getRendererFactory()
4163 28 Feb 08 nicklas 123     @see Extension#getRendererFactory()
4163 28 Feb 08 nicklas 124   */
4158 22 Feb 08 nicklas 125   public void renderDefault()
4158 22 Feb 08 nicklas 126   {
4870 01 Apr 09 nicklas 127     renderDefault(null);
4870 01 Apr 09 nicklas 128   }
4870 01 Apr 09 nicklas 129   
4870 01 Apr 09 nicklas 130   /**
4870 01 Apr 09 nicklas 131     Render all actions by wrapping the default renderers by the
4870 01 Apr 09 nicklas 132     given wrapping renderer. 
4870 01 Apr 09 nicklas 133     @param wrapper A wrapping renderer, or null to not wrap
4870 01 Apr 09 nicklas 134       the default renderers
4870 01 Apr 09 nicklas 135     @since 2.12
4870 01 Apr 09 nicklas 136   */
4870 01 Apr 09 nicklas 137   public void renderDefault(WrappingRenderer<A> wrapper)
4870 01 Apr 09 nicklas 138   {
4168 04 Mar 08 nicklas 139     ActionIterator<A> it = iterate();
4158 22 Feb 08 nicklas 140     while (it.hasNext())
4158 22 Feb 08 nicklas 141     {
4233 17 Apr 08 nicklas 142       A action = null;
4233 17 Apr 08 nicklas 143       Renderer<? super A> renderer = null;
4233 17 Apr 08 nicklas 144       try
4163 28 Feb 08 nicklas 145       {
4618 30 Oct 08 nicklas 146         if (clearErrors) it.clearError();
4233 17 Apr 08 nicklas 147         action = it.next();
4233 17 Apr 08 nicklas 148         renderer = it.getRenderer();
4233 17 Apr 08 nicklas 149         if (renderer == null) 
4233 17 Apr 08 nicklas 150         {
4233 17 Apr 08 nicklas 151           throw new NullPointerException("No renderer for extension: " + it.getExtension());
4233 17 Apr 08 nicklas 152         }
4870 01 Apr 09 nicklas 153         if (wrapper != null)
4870 01 Apr 09 nicklas 154         {
4870 01 Apr 09 nicklas 155           wrapper.setParent(renderer);
4870 01 Apr 09 nicklas 156           renderer = wrapper;
4870 01 Apr 09 nicklas 157         }
8144 21 Apr 23 nicklas 158         renderer.render(action, it.getExtension());
4163 28 Feb 08 nicklas 159       }
4322 30 May 08 nicklas 160       catch (Throwable t)
4233 17 Apr 08 nicklas 161       {
5486 12 Nov 10 nicklas 162         it.setError("Could not render action '" + action + "' with renderer '" + 
4322 30 May 08 nicklas 163             renderer + "'", t);
4233 17 Apr 08 nicklas 164       }
4158 22 Feb 08 nicklas 165     }
4158 22 Feb 08 nicklas 166   }
4870 01 Apr 09 nicklas 167
4158 22 Feb 08 nicklas 168   
4163 28 Feb 08 nicklas 169   /**
4163 28 Feb 08 nicklas 170     Render all actions using a specific renderer. The given 
4163 28 Feb 08 nicklas 171     renderer will be used even if an extension point has provided
4163 28 Feb 08 nicklas 172     a renderer factory and disallowed overriding it.
4163 28 Feb 08 nicklas 173     
4163 28 Feb 08 nicklas 174     @see ExtensionPoint#getRendererFactory()
4163 28 Feb 08 nicklas 175     @see ExtensionPoint#allowRendererOverride()
4163 28 Feb 08 nicklas 176   */
4158 22 Feb 08 nicklas 177   public void render(Renderer<A> renderer)
4158 22 Feb 08 nicklas 178   {
7272 19 Jan 17 nicklas 179     renderWithEvent(renderer, null);
7272 19 Jan 17 nicklas 180   }
7272 19 Jan 17 nicklas 181   
7272 19 Jan 17 nicklas 182   /**
7272 19 Jan 17 nicklas 183     Render all actions using a specific renderer and send the specified event
7272 19 Jan 17 nicklas 184     to event handlers.
7272 19 Jan 17 nicklas 185     @param event The event to send or null to not send any event
7272 19 Jan 17 nicklas 186     @since 3.10
7272 19 Jan 17 nicklas 187   */
7272 19 Jan 17 nicklas 188   public void renderWithEvent(Renderer<A> renderer, EventType event)
7272 19 Jan 17 nicklas 189   {
4618 30 Oct 08 nicklas 190     ActionIterator<A> it = iterate();
4158 22 Feb 08 nicklas 191     while (it.hasNext())
4158 22 Feb 08 nicklas 192     {
4233 17 Apr 08 nicklas 193       A action = null;
4233 17 Apr 08 nicklas 194       try
4233 17 Apr 08 nicklas 195       {
4618 30 Oct 08 nicklas 196         if (clearErrors) it.clearError();
4233 17 Apr 08 nicklas 197         action = it.next();
8144 21 Apr 23 nicklas 198         renderer.render(action, it.getExtension());
7275 24 Jan 17 nicklas 199         if (event != null) it.handleEvent(event);
4233 17 Apr 08 nicklas 200       }
4322 30 May 08 nicklas 201       catch (Throwable t)
4233 17 Apr 08 nicklas 202       {
5486 12 Nov 10 nicklas 203         it.setError("Could not render action '" + action + "' with renderer '" + 
4322 30 May 08 nicklas 204             renderer + "'", t);
4233 17 Apr 08 nicklas 205       }
4158 22 Feb 08 nicklas 206     }
7272 19 Jan 17 nicklas 207     
4158 22 Feb 08 nicklas 208   }
5598 30 Mar 11 nicklas 209
5598 30 Mar 11 nicklas 210   @Override
5598 30 Mar 11 nicklas 211   public Iterator<A> iterator()
5598 30 Mar 11 nicklas 212   {
5598 30 Mar 11 nicklas 213     return iterate();
5598 30 Mar 11 nicklas 214   }
4158 22 Feb 08 nicklas 215 }