3.12.5. ActionItemVisibilityAspect

Ein IActionItemVisibilityAspect definiert die Sichtbarkeit für eine oder mehrere Action Item Models. Mit Hilfe der folgenden Methode kann auf einem IActionItemModelBuilder ein IActionItemVisibilityAspect für ein einzelnes Action Item Model gesetzt, bzw. hinzugefügt werden:

    IActionItemModelBuilder addVisibilityAspect(IActionItemVisibilityAspect visibilityAspect);

Mit Hilfe eines IActionItemVisibilityAspectPlugin kann ein Aspekt zu allen Action Items Models hinzugefügt werden.

Die Schnittstelle IActionItemVisibilityAspect

Die Schnittstelle IActionItemVisibilityAspect hat die folgende Methode:

    IPriorityValue<Boolean, LowHighPriority> getVisibility(IAction action);

Dabei hat ein IPriorityValue<Boolean, LowHighPriority> folgenden Methoden:

    Boolean getValue();

    LowHighPriority getPriority();

Der value definiert, ob die Action sichtbar sein soll oder nicht. Die enum LowHighPriority hat zwei mögliche Werte:

    LOW,

    HIGH;

Man kann also festlegen, mit welcher Priorität die Action sichtbar sein soll oder nicht. Dies kann hilfreich sein, wenn mehr als ein Aspekt definiert ist.

Zum Beispiel könnte ein Aspekt alle Actions ausblenden wollen, für die der angemeldete Nutzer kein Ausführungsrecht in der Rechteverwaltung besitzt. Ein solcher Aspekte würden für visible == true die Priorität LOW setzen, was soviel bedeutet wie: Aus meiner Sicht sichtbar, außer jemand anders sagt mit höherer Priorität visible=false. Für visible == false würde die Priorität HIGH verwendet werden, was soviel bedeutet wie:Egal was andere nach mir sagen, die Action soll nicht sichtbar sein“.

Hat die Sichtbarkeit von zwei Aspekten beide Male die Priorität HIGH, wird der Aspekt berücksichtigt, welcher zuerst hinzugefügt wurde. Beim Action Item Visibility Aspect Plugin kann dafür eine order angegeben werden.

Um das obere Beispiel zu erweitern, könnte ein Aspekt die Aufgabe haben, bestimmte Actions immer anzuzeigen, auch wenn man kein Recht zur Ausführung hat (z.B. weil keine Lizenz erworben wurde). Dennoch soll der Nutzer, sozusagen als Teaser, sehen dass eine bestimmte Aktion existiert, um den Wunsch zu wecken, eine Lizenz zu erwerben. Ein solcher Aspekt würde für visible == true die Priorität HIGH und für visible == false die Priorität LOW verwenden.

Enabled State Visibility Aspect

Die Klasse org.jowidgets.tools.model.item.EnabledStateVisibilityAspect implementiert einen Visibility Aspekt, welcher alle Actions ausblendet, die nicht enabled sind. Der Source Code soll als Beispiel für die Implementierung eines IActionItemVisibilityAspect dienen:

  1  public final class EnabledStateVisibilityAspect implements IActionItemVisibilityAspect {
  2  
  3      private static final IPriorityValue<Boolean, LowHighPriority> NOT_VISIBLE_HIGH 
  4          = new PriorityValue<Boolean, LowHighPriority>(Boolean.FALSE, LowHighPriority.HIGH);
  5  
  6      private static final IPriorityValue<Boolean, LowHighPriority> VISIBLE_LOW 
  7          = new PriorityValue<Boolean, LowHighPriority>(Boolean.TRUE, LowHighPriority.LOW);
  8  
  9      @Override
 10      public IPriorityValue<Boolean, LowHighPriority> getVisibility(final IAction action) {
 11          if (action != null) {
 12              final boolean enabled = action.isEnabled();
 13              if (!enabled) {
 14                  return NOT_VISIBLE_HIGH;
 15              }
 16              else {
 17                  return VISIBLE_LOW;
 18              }
 19          }
 20          return VISIBLE_LOW;
 21      }
 22  }
Secure Action Item Visiblity Aspect

Der folgende Sichtbarkeitsaspekt stammt aus der jo-client-platform, und versteckt alle Actions, für welche der angemeldete Nutzer kein Ausführungsrecht besitzt[15].

  1  private final class SecureActionItemVisibilityAspect implements IActionItemVisibilityAspect {
  2  
  3      @Override
  4      public IPriorityValue<Boolean, LowHighPriority> getVisibility(final IAction action) {
  5          final ISecureObject<AUTHORIZATION_TYPE> secureObject 
  6              = WrapperUtil.tryToCast(action, ISecureObject.class);
  7          if (secureObject != null) {
  8              if (!authorizationChecker.hasAuthorization(secureObject.getAuthorization())) {
  9                  return NOT_VISIBLE_HIGH;
 10              }
 11          }
 12          return null;
 13      }
 14  }

Das zugehörige Plugin findet sich hier

Die Schnittstelle IActionItemVisibilityAspectPlugin

Um ein Visibilitätsaspekt global hinzuzufügen, kann das IActionItemVisibilityAspectPlugin verwendet werden. Die Schnittstelle hat die folgenden Methoden:

    IActionItemVisibilityAspect getVisibilityAspect();

    int getOrder();

Die erste Methode liefert den Aspekt, die zweite die Order. Alle Plugins werden nach ihrer Order ausgeführt. Um ein Plugin zu registrieren, kann der ServiceLoader Mechanismus verwendet werden, dazu muss eine Datei mit dem Namen org.jowidgets.api.model.item.IActionItemVisibilityAspectPlugin in META-INF/services abgelegt werden, welche die Implementierungen auflistet.

Im Command Action Snipped könnte man zum Beispiel das org.jowidgets.tools.model.item.EnabledStateVisibilityAspectPlugin hinzufügen, dann würde die Save Action nur erscheinen, wenn man speichern kann[16].

Neben der Möglichkeit, das Plugin mit Hilfe eines ServiceLoader zu registrieren, könnte man auch den folgenden Code hinzufügen (z.B. bevor das Frame erzeugt wird):

  1      ActionItemVisibilityAspectPlugin.registerPlugin(new EnabledStateVisibilityAspectPlugin());

Das Ergebnis würde, unabhängig mit welcher Methode das Plugin registriert wurde, dann so aussehen (einmal mit und einmal ohne Save Action):

Es ist zu beachten, dass der Button nicht automatisch ausgeblendet wurde. Das Ausblenden ist derzeit auf Menüs und Toolbars beschränkt. Um die Funktion selbst zu implementieren, könnte die folgende Methode auf der Klasse ActionItemVisibilityAspectPlugin verwendet werden, um die Sichtbarkeit der Action zu erhalten:

    public static IPriorityValue<Boolean, LowHighPriority> getVisibility(final IAction action) {...}

Diese liefert die Visibilität auf Basis aller registrierten Plugins. Um den Button im Command Action Snipped ebenfalls automatisch auszublenden, könnte man die folgende Methode hinzufügen:

  1  private void setButtonVisibility(final IButton button, final IAction action) {
  2      final IPriorityValue<Boolean, LowHighPriority> visibility 
  3          = ActionItemVisibilityAspectPlugin.getVisibility(action);
  4      if (visibility != null) {
  5          button.setVisible(visibility.getValue().booleanValue());
  6      }
  7      else {
  8          button.setVisible(true);
  9      }
 10  }

Und diese wie folgt aufrufen:

  1      ...
  2      
  3      setButtonVisibility(saveButton, saveAction);
  4      saveAction.getActionChangeObservable().addActionChangeListener(new ActionChangeAdapter() {
  5          @Override
  6          public void enabledChanged() {
  7              setButtonVisibility(saveButton, saveAction);
  8              frame.layoutLater();
  9          }
 10      });
 11      
 12      ...


[15] Dabei handelt es sich um einen reinen Convenience Aspekt. In der Service Schicht wird eine solche Aktion zusätzlich abgelehnt.

[16] Dies soll nur der Anschauung dienen. Nach Meinung des Autors ist es besser, den disabled Reason anzuzeigen, anstatt den Save Button auszublenden.


Siehe auch PDF Version dieses Dokuments, Jowidgets API Spezifikation