package org.richfaces.cdk.generate.taglib; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.text.MessageFormat; import javax.el.ValueExpression; import org.richfaces.cdk.model.AttributeModel; import org.richfaces.cdk.model.ClassName; import org.richfaces.cdk.model.EventModel; import org.richfaces.cdk.model.PropertyBase; /** * User: Gleb Galkin Date: 23.02.11 */ public enum ListenerAttribute { @Description(derivator = NoneDerivator.class, base = "If present, this attribute refers to the value of one of the exposed attached objects within the composite component inside of which this tag is nested.") FOR("for", false, ClassName.get(String.class)), @Description(derivator = ListenerNameDerivator.class, base = "Value binding expression that evaluates to an object that implements {0}.") BINDING("binding", false, ClassName.get(ValueExpression.class)), @Description(derivator = EventNameDerivator.class, base = "MethodExpression representing an action listener method that will be notified when this component is activated by the user. The expression must evaluate to a public method that takes an {0} parameter, with a return type of void, or to a public method that takes no arguments with a return type of void") LISTENER("listener", false, ClassName.get(ValueExpression.class)), @Description(derivator = ListenerNameDerivator.class, base = "Fully qualified Java class name of an {0} to be created and registered.") TYPE("type", false, ClassName.get(ValueExpression.class)); private AttributeModel attribute; ListenerAttribute(String name, boolean required, ClassName type) { this.attribute = new AttributeModel(name, required, type, ""); } public PropertyBase derivateProperty(EventModel model) { String description = getDescription(model); return new AttributeModel(attribute.getName(), attribute.isRequired(), attribute.getType(), description); } private String getDescription(EventModel model) { try { Description annotation = ListenerAttribute.class.getField(this.toString()).getAnnotation(Description.class); Derivator derivator = annotation.derivator().newInstance(); return derivator.derive(annotation.base(), model); } catch (Exception e) { throw new IllegalStateException(e); } } public abstract static class Derivator { public String derive(String descriptionBase, EventModel model) { return MessageFormat.format(descriptionBase, derivateParameters(model)); } public abstract Object[] derivateParameters(EventModel model); } static class NoneDerivator extends Derivator { @Override public Object[] derivateParameters(EventModel model) { return new Object[] {}; } } static class ListenerNameDerivator extends Derivator { @Override public Object[] derivateParameters(EventModel model) { return new Object[] { model.getListenerInterface().getSimpleName() }; } } static class EventNameDerivator extends Derivator { @Override public Object[] derivateParameters(EventModel model) { return new Object[] { model.getType().getSimpleName() }; } } @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD }) @Inherited private @interface Description { String base(); Class<? extends Derivator> derivator(); } }