2009-07-14 11 views
0

Vom JSF 1.2 revB mrel2 spec: unten auf der Seite 65adf - howto modify komponenten in baum?

■ Es muss möglich sein für die Anwendung während des Anforderungsverarbeitungszyklus (außer während der Wiedergabe der Ansicht), um den Komponentenbaum jederzeit programmatisch zu ändern und das System verhält sich wie erwartet. Zum Beispiel muss folgendes erlaubt sein. Eine Änderung der Ansicht beim Rendern kann zu undefinierten Ergebnissen führen. Es muss möglich sein, dass Komponenten, die durch das Templating-System (wie JSP) hinzugefügt wurden, vor dem Rendern aus dem Baum entfernt werden können. Es muss möglich sein, programmatisch Komponenten zur Struktur hinzuzufügen und sie an der richtigen Stelle in der Hierarchie rendern zu lassen. Es muss möglich sein, Komponenten in der Baumstruktur vor dem Rendern neu zu ordnen. Diese Manipulationen erfordern, dass alle Komponenten, die der Struktur hinzugefügt werden, IDs aufweisen, die innerhalb des Bereichs der nächsten übergeordneten NamingContainer-Komponente eindeutig sind. Der Wert der Eigenschaft rendernChildren wird wie erwartet behandelt und kann entweder wahr oder falsch sein.

Also wie macht man das in adf 11g? Ich versuche ein anwendungsweites Autorisierungssystem zu implementieren, in dem Komponenten basierend auf den Rollen eines Benutzers sichtbar/bearbeitbar sind. Ich kann jedoch keine Möglichkeit finden, in adf einzuhaken, um Komponenten zu modifizieren (zB RichInputText.setDisabled (true)), bevor die Antwort ausgegeben wird. Ich habe es mit beiden PhaseListenern und ViewHandlern versucht. Beides scheint mir die oben erwähnte Funktionalität nicht zu ermöglichen. Also was gibt es? Habe ich kein Glück? Fehle ich etwas?

Danke, Ben

public class AuthorizationPhaseListener implements PhaseListener { 
    ... 
    public PhaseId getPhaseId() { 
    return PhaseId.RENDER_RESPONSE; // I've also tried in the other phases including ALL_PHASES 
    } 
    public void beforePhase(PhaseEvent p1) { 
    // relevant ui components don't yet exist 
    ... 
    } 
    public void afterPhase(PhaseEvent p1) { 
    // relevant ui components exist, but have already been written to the stream, thus it's too late to modify them 
    ... 
    } 
    ... 
} 

public class MyCustomViewHandler extends ViewHandlerWrapper { 
    ... 
    @Override 
    public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException { 
    AuthorizationService as = (AuthorizationService)RiscsContext.getCurrentInstance().getBean("AuthorizationService"); 
    // relevant ui components don't yet exist 
    as.applyAuthorization(); 
    super.renderView(context, viewToRender); 
    // relevant ui components exist, but have already been written to the stream, thus it's too late to modify them 
    as.applyAuthorization(); 
    } 
    ... 
} 

Antwort

0

Nach meinem (begrenzt) durch die Dokumentation der Suche ist das UIViewRoot Objekt der Wurzelknoten der Baumansicht. Sie können die getChildren-Methoden verwenden, um die geeigneten UIComponents zu finden und Ihre Änderungen vorzunehmen. Ich würde jedoch einen anderen Weg vorschlagen.

Wenn Sie den Autorisierungsdienst als Bean verfügbar machen, können Sie die Methoden direkt zum Markup hinzufügen. Zum Beispiel ...

public class User { 
... 
Map<String, Boolean> allowedRoles; 
... 
public Map<String, Boolean> getAllowedRoles { return allowedRoles; } 
} 

<h:inputText value="#{SomethingImportant}" disabled="!#{User.allowedRoles['importantRole']}/> 

Noch besser wäre ein Sicherheitsframework, das dies noch mehr vereinfachen würde.

+0

Drew, immer UIViewRoot nicht, weil nicht helfen, wie ich dokumentiert in den Kommentaren ein Folgendes ist wahr: // relevante ui-Komponenten existieren noch nicht // relevante ui-Komponenten existieren, wurden aber bereits in den Streamgeschrieben Ich würde lieber nicht das deaktivierte Attribut zu allen meiner JSFs hinzufügen. Zum einen ist es langweilig. Zum anderen lassen wir die Benutzer Rollen einrichten. Unsere Anforderungen sind also viel feiner, als es die Lösung zulässt. – andersonbd1

+0

Wir verwenden ein Sicherheits-Framework (Acegi), um uns zu starten, aber unsere Anforderungen gehen tiefer. Ich schreibe gerade unseren eigenen Sicherheitsrahmen. Ich habe AOP tun, was notwendig ist.Es ist ein Hack, aber es funktioniert. – andersonbd1

0

Es ermöglicht den Zugriff/Änderung der UI-Komponenten in der Struktur, wenn es lokalisierbar ist. Sie müssen die Clientkomponenten-ID angeben, während Sie findComponent() verwenden. Das einzige Problem bleibt, dass es Ihnen keinen Zugriff/control für das Laden der ersten Seite (restore_view) gibt. :-( Für das ab jetzt nur 1 Weise konnte ich finden, dass EL in jspx/jsp/jsff spezifiziert.

2

Sie wirklich müssen dies auf der Präsentationsseite tun tun Sie es nicht mit einem Phaselistener, dort es ist nicht für weise Nutzung des rendered Attribut Make Hier einige grundlegende Beispiele, wie Sie davon Gebrauch machen können.. von

<h:someComponent rendered="#{bean.booleanValue}" /> 
<h:someComponent rendered="#{bean.intValue > 10}" /> 
<h:someComponent rendered="#{bean.objectValue == null}" /> 
<h:someComponent rendered="#{bean.stringValue != 'someValue'}" /> 
<h:someComponent rendered="#{!empty bean.collectionValue}" /> 
<h:someComponent rendered="#{!bean.booleanValue && bean.intValue != 0}" /> 
<h:someComponent rendered="#{bean.stringValue == 'oneValue' || bean.stringValue == 'anotherValue'}" />