Eigene TagLib schreiben

robgeb

Mitglied
Hi. Ich bin gerade am schreiben einer eigenen Tag-Library.

folgende grundlegenden Technologien werden angewandt: JBoss4.2.3 und JSF

Solange alle Attribute eines Tags primitive Datentypen bleiben klappt ja alles wunderbar.
Jedoch will ich jetzt eine komplexe Klasse angeben. Dazu brauche ich einen weiteren Property-Editor der dann diese Klasse unterstützt. Eigentlich kein Problem, dachte ich...

hier mal der PropertyEditor
Java:
package de.meine_energie.web.taglib.property_editors;

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.beans.PropertyChangeListener;
import java.beans.PropertyEditor;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;

import de.meine_energie.mbean.SystemMBean;
import de.meine_energie.permission.Permission;
import de.meine_energie.web.mbean.workspace.WorkspaceAction;

public class PermissionPropertyEditor implements PropertyEditor {
	
	private Permission permission;

	@Override
	public String getAsText() {
		System.out.println("getAsText");
		return null;
	}

	@Override
	public Object getValue() {
		System.out.println("getValue");
		return permission;
	}

	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		
		System.out.println("setAStext "+text);
		
		ELContext context = FacesContext.getCurrentInstance().getELContext();
		ELResolver resolver = context.getELResolver();
		
		permission = (Permission) resolver.getValue(context, null, text);
		System.out.println("permission1: "+permission);

	}

	@Override
	public void setValue(Object value) {
		System.out.println("setValue in PropertyEditor");
		permission = (Permission) value;
	}

}

(unwichtige Methoden hab ich mal weggekürzt)

auf jeden Fall wird zuerst der PropertyEditor mit setAsText aufgerufen. Diese Angabe die da folgt (ExpressionLanguage) habe ich versucht aufzulösen. Aber komplett ohne Erfolg. Man Sieht noch wie ich dachte, dass es gehen müssen. Über javax.el.ELResolver.getValue(...) aber anscheinend weit gefehlt. Kann mir jemand helfen und sagen wie ich den Wert bekomme, der mir per ExpressionLanguage gegeben wird.
Sinnvolle Beispiele sind keine zu finden, oder ich hab nach den falschen Begriffen gesucht.

... ich wär für jede Hilfe dankbar!

vG Robert Gebhardt
 
Hallo,

damit du den Wert einer ELExpression , wie z.B. von #{bean.value} bekommst, kannst du die ExpressionFactory (ab JSF 1.2) benutzen. Mit der erzeugst du dir zuerst mal die benötigte ValueExpression bzw. MethodExpression. In deinem Fall gehe ich mal von einer ValueExpression aus.

Das ganze sieht dann ungefähr so aus:
Java:
FacesContext fc = FacesContext.getCurrentInstance();
ELContext elc = fx.getELContext();
ExpressionFactory ef = ctx.getApplication().getExpressionFactory();

String expression = "#{bean.value}";
// der letzte Parameter ist der Typ, denn du zurück erwartest - bei dir Permission.class		
ValueExpression ve =ef.createValueExpression(el,expression, Permission.class);
//hier wird die Expression dann ausgewertet
Permission perm = (Permission)ve.getValue(ctx.getELContext());

Soweit zur eigentlichen Frage. Was ich persönlich jetzt nicht verstehe - warum brauchst du einen PropertyEditor :confused:
Du gibst dem Tag-Attribut doch immer eine EL als Wert, oder? Da kannst du doch direkt ValueExpression bei den Gettern und Settern im Tag-Handler benutzen.

Grüße
THMD
 
Hi,
an und für ich ist das eine Super Lösung, zwar waren Fehler drin, aber ich das ist ja kein Problem.
Hier mal die richtige Version des Codes:

Java:
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
ExpressionFactory expressionFactory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();

String text = "#{bean.name}";

ValueExpression permissionExpression = expressionFactory.createValueExpression(elContext, text, Permission.class);
Permission permission = (Permission) permissionExpression.getValue(elContext);

Und nun zur Erklärung den Property-Editor.
Um nicht in jedem einzelnen Tag aus einer EL eine "Permission" zu bekommen, sage ich einfach, dass meine Tag-Klasse den Typ "Permission" erwartet und für "Permission" ist ein bestimmter Property-Editor registriert, über den dann aus der EL eine Permission herangeholt wird.
(Hoffe das war jetzt kein zu großes Kauderwelsch)

Nur für mich bäumt sich ein neues Problem auf. Ich gebe in dem Tag ein Attribut einer Schleifenvariable an (<a4j:repeat>). Dadurch scheine ich nicht auf das Attribut über die genannte Methode zugreifen zu können.

Ich hab auch schon getestet. Normale Elemente der Backing-Bean kann ich über die Variante erreichen, jedoch keine aus der Schleife :(

Gibt es dafür einen anderen Weg oder kann mir jemand verraten wo ich da idealerweise schauen kann?
Ich hab ja bisher nichtmal sinnvolle Literatur zum Schreiben eigener Tag-Libs gefunden.

vG Robert Gebhardt
 
Hallo,

Um nicht in jedem einzelnen Tag aus einer EL eine "Permission" zu bekommen, sage ich einfach, dass meine Tag-Klasse den Typ "Permission" erwartet und für "Permission" ist ein bestimmter Property-Editor registriert, über den dann aus der EL eine Permission herangeholt wird.
äh aber damit machst du doch im Endeffekt das gleiche, als wenn du direkt bei deinem Tag eine ValueExpression als Wert nimmst. Du bekommst für jeden Tag eine Permission

... Ich gebe in dem Tag ein Attribut einer Schleifenvariable an (<a4j:repeat>). Dadurch scheine ich nicht auf das Attribut über die genannte Methode zugreifen zu können.
naja relativ einfach gesprochen - a4j:repeat funktioniert nur für JSF-Komponenten. Du hast aber "nur" einen JSP-Tag. Du müsstest dir also eine eigene Komponente erzeugen. Damit bekommst du dann auch innerhalb von a4j:repeat einen Wert.

Alternativ könntest du einfach <c:forEach> benutzen, falls das möglich ist, dann sollte auch dein Tag einen Wert bekommen.

Grüße
THMD
 
Danke

du hast mir das Wochenende gerettet :)

Also werd ich mich dran machen eine JSF-Komponente zu bauen.

Nur mal so zur Info wegen dem Property-Editor. Den nehm ich um nicht in jedem eigenen Tag wieder aus der Value-Expression eine "Permission" zu bekommen.
Daher der Property-Editor um doppelten Code zu vermeiden. Aber das scheint ja jetzt erstmal für mich hinfällig zu sein.

Aber nochmals vielen Dank, du hast mir einige depressive Tage erspart ;-)

vG Robert Gebhardt
 
So für alle die hier rein schauen und nach einer Lösung suchen ...

ich hab jetzt im Forum von Richfaces nachgefragt, da auch JSF-Komponenten mir kein Ergebnis brachten.
Das Problem ist mit einer JSF-Komponente ähnlich wie mit einer eigenen einfachen TagLib. Die eigene Komponente wird zum Aufbau des Komponentenbaumes evaluiert. Alles was jedoch JSF-Iteration ist, wird erst zur Laufzeit evauliert. Daher funktioniert keine der Möglichkeiten.
Eine Möglichkeit wäre das nutzen von Facelets, was für meinen Fall aber zu umständlich ist, sodass ich mir eine andere Möglichkeit einfallen lassen muss.
 
Zurück