Perform Action in MQTT Subscriber - mqtt

This mqtt subscriber code works fine. I can easily subscribe to messages which are published at broker.hivemq.com with respective topic.
public class AccelerometerSubscriber implements MqttCallback,
IMqttActionListener {
public static void main(String[] args) throws MqttException {
int QUALITY_OF_SERVICE = 2;
MqttClient client=new MqttClient("tcp://broker.hivemq.com:1883",
MqttClient.generateClientId());
client.setCallback( new SimpleMqttCallBack() );
client.connect();
System.out.println("Subscribing ....");
client.subscribe("MQTT Examples"); }
System.out.println("some action"); //------------right here--------------
public void connectionLost(Throwable throwable) {
System.out.println("Connection to MQTT broker lost!"); }
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
System.out.println("Message received:\n\t"+ new String(mqttMessage.getPayload()) );
}
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
// not used in this example
}}
Now I want to perform action only when a message is received. I'm unable to do that.

You have a class (AccelerometerSubscriber) that implements the interface MqttCallback, use an instance of it instead of doing client.setCallback( new SimpleMqttCallBack() );
public class AccelerometerSubscriber implements MqttCallback, IMqttActionListener {
public static void main(String[] args) throws MqttException {
AccelerometerSubscriber as = new AccelerometerSubscriber();
int QUALITY_OF_SERVICE = 2;
MqttClient client = new MqttClient("tcp://broker.hivemq.com:1883", MqttClient.generateClientId());
client.setCallback(as);
client.connect();
System.out.println("Subscribing ....");
client.subscribe("MQTT Examples");
}
#Override
public void connectionLost(Throwable throwable) {
System.out.println("Connection to MQTT broker lost!");
}
#Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
//message is received is here!!!
System.out.println("Message received:\n\t" + new String(mqttMessage.getPayload()));
}
#Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("deliveryComplete");
}
#Override
public void onFailure(IMqttToken arg0, Throwable arg1) {
System.out.println("onFailure");
}
#Override
public void onSuccess(IMqttToken arg0) {
System.out.println("onSuccess");
}
}

Related

Spring Websocket: how to subscribe to a topic and fetch the last message?

I have the following spring websocket stomp client:
var client = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(client);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(mapper);
stompClient.setMessageConverter(converter);
StompSessionHandler sessionHandler = new StompSessionHandler() {
#Override
public void afterConnected(final StompSession session, final StompHeaders connectedHeaders) {
session.subscribe("/topic/senha", this);
}
...
#Override
public void handleFrame(final StompHeaders headers, final Object payload) {
//get notification here
}
};
stompClient.connect(uri.toString(), sessionHandler);
Server:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(final MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(final StompEndpointRegistry registry) {
registry.addEndpoint("/ws");
}
}
I get notified in handleFrame about new messages.
But the topic has messages in it's history.
I want to fetch the last message/state from the topic when connected. How to do it?

java.lang.NoSuchMethodError using JDBI

public class MyApplication extends Application<MyConfiguration> {
final static Logger LOG = Logger.getLogger(MyApplication.class);
public static void main(final String[] args) throws Exception {
new MyApplication().run(args);
}
#Override
public String getName() {
return "PFed";
}
#Override
public void initialize(final Bootstrap<MyConfiguration> bootstrap) {
// TODO: application initialization
bootstrap.addBundle(new DBIExceptionsBundle());
}
#Override
public void run(final MyConfiguration configuration,
final Environment environment) {
// TODO: implement application
final DBIFactory factory = new DBIFactory();
final DBI jdbi = factory.build(environment, configuration.getDataSourceFactory(), "postgresql");
UserDAO userDAO = jdbi.onDemand(UserDAO.class);
userDAO.findNameById(1);
UserResource userResource = new UserResource(new UserService(userDAO));
environment.jersey().register(userResource);
}
I get the the following error at findNameById.
java.lang.NoSuchMethodError: java.lang.Object.findNameById(I)Ljava/lang/String;
at org.skife.jdbi.v2.sqlobject.CloseInternalDoNotUseThisClass$$EnhancerByCGLIB$$a0e63670.CGLIB$findNameById$5()
}
public interface UserDAO {
#SqlQuery("select userId from user where id = :email")
User isEmailAndUsernameUnique(#Bind("email") String email);
#SqlQuery("select name from something where id = :id")
String findNameById(#Bind("id") int id);
}

NestedSlot presenter with own url- how to setup url for NestedSlot presenters

I have parent presenter: UsersListPresenter that contains nested presenter: UserPresenter in NestedSlot.
public class UsersListPresenter extends ApplicationPresenter<UsersListPresenter.MyView, UsersListPresenter.MyProxy> implements UsersListUiHandlers,
OpenWindowEvent.OpenModaHandler, UserAddedEvent.UserAddedHandler {
#ProxyStandard
#NameToken(ClientRouting.Url.users)
#UseGatekeeper(IsUserLoggedGatekeeper.class)
public interface MyProxy extends TabContentProxyPlace<UsersListPresenter> {}
#TabInfo(container = AppPresenter.class)
static TabData getTabLabel(IsUserLoggedGatekeeper adminGatekeeper) {
return new MenuEntryGatekeeper(ClientRouting.Label.users, 1, adminGatekeeper);
}
public interface MyView extends View, HasUiHandlers<UsersListUiHandlers> {
void setUsers(List<UserDto> users);
void addUser(UserDto user);
}
public static final NestedSlot SLOT_USER_WINDOW = new NestedSlot();
//interface Driver extends SimpleBeanEditorDriver<UserDto, UserEditor> {}
private static final UserService userService = GWT.create(UserService.class);
private AppPresenter appPresenter;
private UserTestPresenter userPresenter;
#Inject
UsersListPresenter(EventBus eventBus, MyView view, MyProxy proxy, AppPresenter appPresenter, UserTestPresenter userPresenter) {
super(eventBus, view, proxy, appPresenter, AppPresenter.SLOT_TAB_CONTENT);
this.appPresenter = appPresenter;
this.userPresenter = userPresenter;
getView().setUiHandlers(this);
}
#Override
protected void onBind() {
super.onBind();
updateList();
setInSlot(SLOT_USER_WINDOW, userPresenter);
addRegisteredHandler(OpenWindowEvent.getType(), this);
}
#Override
protected void onReveal() {
super.onReveal();
initializeApplicationUiComponents(ClientRouting.Label.users);
}
#Override
public void onOpenModal(OpenWindowEvent event) {
openModal(event.getUser());
}
#Override
public void openModal(UserDto user) {
userPresenter.openModal(user);
}
}
public class UsersListView extends ViewWithUiHandlers<UsersListUiHandlers> implements UsersListPresenter.MyView {
interface Binder extends UiBinder<Widget, UsersListView> {}
#UiField
SimplePanel windowSlot;
#Inject
UsersListView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public void setInSlot(Object slot, IsWidget content) {
if (slot == UsersListPresenter.SLOT_USER_WINDOW) {
windowSlot.setWidget(content);
}
};
}
public class UserTestPresenter extends Presenter<UserTestPresenter.MyView, UserTestPresenter.MyProxy> implements UserTestUiHandlers {
public interface MyView extends View, HasUiHandlers<UserTestUiHandlers> {
void openModal(UserDto user);
}
#ProxyStandard
#NameToken("/user/{userid}")
public interface MyProxy extends ProxyPlace<UserTestPresenter> {
}
private PlaceManager placeManager;
#Inject
public UserTestPresenter(EventBus eventBus, MyView view, MyProxy proxy, PlaceManager placeManager) {
super(eventBus, view, proxy, UsersListPresenter.SLOT_USER_WINDOW);
this.placeManager = placeManager;
getView().setUiHandlers(this);
}
#Override
public void prepareFromRequest(PlaceRequest request) {
GWT.log("Prepare from request " + request.getNameToken());
}
#Override
protected void onReveal() {
super.onReveal();
};
public void openModal(UserDto user) {
getView().openModal(user);
}
#Override
public void onSave(UserDto user) {
// TODO Auto-generated method stub
MaterialToast.fireToast("onSaveClick in new presenter for " + user.toString());
}
#Override
public void onClose() {
PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken("/users/{userid}").with("userid", "list").build();
placeManager.revealPlace(placeRequest);
}
public class UserTestView extends ViewWithUiHandlers<UserTestUiHandlers> implements UserTestPresenter.MyView {
interface Binder extends UiBinder<Widget, UserTestView> {}
#UiField
MaterialRow main;
#UiField
MaterialWindow window;
#UiField
MaterialLabel userName, userFullName;
#UiField
MaterialButton saveButton;
private HandlerRegistration saveButtonClickHandler;
#Inject
UserTestView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
// adding default click handler
saveButtonClickHandler = saveButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {}
});
}
#Override
public void openModal(final UserDto user) {
userName.setText(user.getEmail());
userFullName.setText(user.getId() + " " + user.getEmail());
saveButtonClickHandler.removeHandler();
saveButtonClickHandler = saveButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
getUiHandlers().save(user);
}
});
window.openWindow();
}
}
when user from list is clicked the window with clicked users is opened. At this moment url should change from http://localhost:8080/cms/#/users/list to http://localhost:8080/cms/#/user/3
for better understanding below is screencast from that code:
and now some job done, but still not ideal:
here is my gwtp configuration:
public class ClientModule extends AbstractPresenterModule {
#Override
protected void configure() {
bind(RestyGwtConfig.class).asEagerSingleton();
install(new Builder()//
.defaultPlace(ClientRouting.HOME.url)//
.errorPlace(ClientRouting.ERROR.url)//
.unauthorizedPlace(ClientRouting.LOGIN.url)//
.tokenFormatter(RouteTokenFormatter.class).build());
install(new AppModule());
install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));
bind(CurrentUser.class).in(Singleton.class);
bind(IsAdminGatekeeper.class).in(Singleton.class);
bind(IsUserLoggedGatekeeper.class).in(Singleton.class);
bind(ResourceLoader.class).asEagerSingleton();
}
}
As You can see I use tokenFormatter(RouteTokenFormatter.class)
how it can be achieved with gwtp framework?
One way to achieve this is to change the URL of your UserListPresenter to support passing in the user id as an optional parameter:
#NameToken("/users/{userid}")
public interface MyProxy extends ProxyPlace<UserListPresenter> {
}
You need to override the prepareFromRequest method of your UserListPresenter and there you check if the userid is set and open your modal window if it is.
#Override
public void prepareFromRequest(PlaceRequest request) {
String userid = request.getParameter("userid", "list");
if (userid != "list") {
# open modal
}
else {
# close modal
}
}
You also need to change the logic when you click your on a user in your list:
#Override
public void onOpenModal(OpenWindowEvent event) {
PlaceRequest placeRequest = new PlaceRequest.Builder()
.nameToken("/users/{userid}")
.with("userid", event.getUser().getId())
.build();
placeManager.revealPlace(placeRequest);
}
This will change the URL and open the modal.

org.springframework.beans.factory.BeanCreationException using cdi

I am trying to implement authentication and authorization using Spring Security Framework, but I am having a hard time, Im stuck in this exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clienteBO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected br.com.logtec.dao.GenericCrudDAO br.com.logtec.business.GenericCrudBO.dao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'crudDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected javax.persistence.EntityManager br.com.logtec.dao.GenericCrudDAO.entityManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.persistence.EntityManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#javax.inject.Inject(), #br.com.logtec.factory.DataFactory()}
Those are my related classes:
#Named("clienteBO")
public class ClienteBO extends PersonificacaoBO<Cliente>{
private static final long serialVersionUID = 119528316663693560L;
public ClienteBO() {
super();
}
#Override
public Feedback salvar(Cliente instancia) {
instancia.getPessoa().setCliente(true);
//TODO PEGAR EMPRESA DO USUARIO LOGADO
// if(instancia.getEmpresa() == null)
// throw new RuntimeException("O cliente deve obrigatoriamente possuir uma empresa");
return super.salvar(instancia);
}
#Override
public Feedback salvar(Cliente instancia, CrudDAO<Cliente> dao) {
instancia.getPessoa().setCliente(true);
return super.salvar(instancia, dao);
}
#Override
protected Exemplo criarExemplo(Cliente pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return super.criarExemplo(pesquisa);
}
#Override
public Feedback salvar(Collection<Cliente> instancias) {
for (Cliente cliente : instancias) {
cliente.getPessoa().setCliente(true);
}
return super.salvar(instancias);
}
#Override
public Feedback salvar(Collection<Cliente> instancias, CrudDAO<Cliente> dao) {
for (Cliente cliente : instancias) {
cliente.getPessoa().setCliente(true);
}
return super.salvar(instancias, dao);
}
}
public abstract class PersonificacaoBO<T extends Personificacao> extends GenericCrudBO<T>{
private static final long serialVersionUID = 5475960092794378740L;
#Override
protected Exemplo criarExemplo(T pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Exemplo exemplo = super.criarExemplo(pesquisa);
exemplo.excludeField("pessoa.cliente");
exemplo.excludeField("pessoa.funcionario");
exemplo.excludeField("pessoa.fornecedor");
exemplo.excludeField("pessoa.usuario");
exemplo.excludeField("pessoa.contador");
return exemplo;
}
}
#Named("crudBO")
public class GenericCrudBO<E extends EntidadeBase> implements CrudBO<E>{
private static final long serialVersionUID = 1L;
private static final String DEFAULT_ERROR_MESSAGE = "Um erro inesperado ocorreu, contate o administrador do sistema.";
private static final String DEFAULT_SUCESS_MESSAGE = "Operação realizada com sucesso!";
#Inject
#Named("crudDAO")
protected GenericCrudDAO<E> dao;
public GenericCrudBO() {
super();
}
public GenericCrudBO(GenericCrudDAO<E> dao) {
super();
this.dao = dao;
}
public Feedback salvar(E instancia, CrudDAO<E> dao) {
Feedback feedback;
try {
dao.atualizar(instancia);
feedback = new Feedback(TipoFeedback.SUCESSO, EtapaFeedback.CADASTRO, DEFAULT_SUCESS_MESSAGE);
} catch (RuntimeException e) {
feedback = new Feedback(TipoFeedback.ERRO, EtapaFeedback.CADASTRO, DEFAULT_ERROR_MESSAGE);
throw e;
}
return feedback;
}
public Feedback salvar(Collection<E> instancias, CrudDAO<E> dao) {
try {
dao.cadastrar(instancias);
return new Feedback(TipoFeedback.SUCESSO, EtapaFeedback.CADASTRO, "Operação realizada com sucesso");
} catch (Exception e) {
return new Feedback(TipoFeedback.ERRO, EtapaFeedback.CADASTRO, "Erro ao salvar, contate o administrador");
}
}
#Override
public Feedback salvar(Collection<E> instancias) {
return salvar(instancias, dao);
}
public Feedback salvar(E instancia) {
return salvar(instancia, dao);
}
#Override
public Feedback deletar(E entidade) {
Feedback feedback;
try {
dao.deletar(entidade);
feedback = new Feedback(TipoFeedback.SUCESSO, EtapaFeedback.CADASTRO, DEFAULT_SUCESS_MESSAGE);
} catch (RuntimeException e) {
feedback = new Feedback(TipoFeedback.ERRO, EtapaFeedback.DELECAO, DEFAULT_ERROR_MESSAGE);
}
return feedback;
}
public E pesquisarPorId(Class<E> clazz, Long id) {
return dao.pesquisarPorId(clazz, id);
}
public E pesquisarPorId(E instancia) {
return dao.pesquisarPorId(instancia);
}
public List<E> pesquisar(Class<E> clazz) {
return dao.pesquisarTodos(clazz);
}
/**
* Pesquisa para entidades simples sem composição
*/
#Override
public List<E> pesquisar(E pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Exemplo exemplo = criarExemplo(pesquisa);
return dao.pesquisar(exemplo);
}
protected Exemplo criarExemplo(E pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Exemplo exemplo = new Exemplo(pesquisa);
exemplo.excludeField("serialVersionUID");
exemplo.setMatchingMode(MatchingMode.ANYWHERE);
exemplo.excludeZeroes();
return exemplo;
}
#Override
public int total(E pesquisa) {
return this.dao.total(pesquisa);
}
public List<E> listarLazy(E pesquisa, int startingAt, int maxPerPage, String sortField, String sortOrder) {
inicializarCamposPesquisa(pesquisa);
return this.dao.listarLazy(pesquisa, startingAt, maxPerPage, sortField, sortOrder);
}
protected void inicializarCamposPesquisa(E pesquisa) {
//método que deverá ser implementado pelas classes filhas que quiserem filtrar os resultados no lazyList
}
public String getListIds(List<EntidadeBase> entidades) {
StringBuilder builder = new StringBuilder('(');
EntidadeBase e = null;
for (int i = 0; i < entidades.size(); i++) {
e = entidades.get(i);
builder.append(e.getId());
if(i < entidades.size()-1) {
builder.append(',');
}
}
builder.append(')');
return builder.toString();
}
#SuppressWarnings("unchecked")
protected Class<E> getClassType() {
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
return (Class<E>) parameterizedType.getActualTypeArguments()[0];
}
}
#Named("crudDAO")
public class GenericCrudDAO<E extends EntidadeBase> implements CrudDAO<E>{
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(CrudDAO.class);
#Inject
#DataFactory
protected EntityManager entityManager;
public GenericCrudDAO() {
super();
}
public GenericCrudDAO(EntityManager entityManager) {
super();
this.entityManager = entityManager;
}
#Override
public void cadastrar(E instancia) {
entityManager.getTransaction().begin();
entityManager.persist(instancia);
entityManager.getTransaction().commit();
}
public void cadastrar(Collection<E> instancias) {
try {
entityManager.getTransaction().begin();
for(E e : instancias) {
entityManager.merge(e);
}
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
throw e;
}
}
#Override
public void atualizar(E instancia) {
entityManager.getTransaction().begin();
entityManager.merge(instancia);
entityManager.getTransaction().commit();
}
#Override
public void deletar(E instancia) {
entityManager.getTransaction().begin();
entityManager.remove(entityManager.merge(instancia));
entityManager.getTransaction().commit();
}
public E pesquisarPorId(Class<E> clazz, Long id) {
return (E) entityManager.find(clazz, id);
}
#SuppressWarnings("unchecked")
public E pesquisarPorId(E instancia) {
Class<E> clazz = (Class<E>) instancia.getClass();
return (E) entityManager.find(clazz, instancia.getId());
}
#SuppressWarnings("unchecked")
public List<E> pesquisarTodos(Class<E> clazz) {
List<E> lista = new ArrayList<E>();
lista = entityManager.createQuery(" FROM " + clazz.getName()).getResultList();
return lista;
}
#Override
public List<E> pesquisar(Exemplo exemplo) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return QBE.using(entityManager).getList(exemplo);
}
#Override
public E pesquisarUnico(Exemplo exemplo) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return QBE.using(entityManager).getSingle(exemplo);
}
#Override
#SuppressWarnings("unchecked")
public List<E> pesquisar(String queryString) {
return entityManager.createQuery(queryString).getResultList();
}
#SuppressWarnings("unchecked")
#Override
public List<E> pesquisar(String queryString, Map<String, Object> param) {
String key = null;
Query query = entityManager.createQuery(queryString);
for(Map.Entry<String, Object> entry : param.entrySet()) {
key = entry.getKey().trim();
key = key.startsWith(":") ? key.substring(1) : key;
query.setParameter(key, entry.getValue());
}
return query.getResultList();
}
public int total(E pesquisa) {
Long count = 0L;
try {;
Query q = entityManager.createQuery("SELECT count(*) FROM "
+ pesquisa.getClass().getName());
count = (Long) q.getSingleResult();
} catch (Exception e) {
LOGGER.error("Erro ao buscar total listagem lazy", e);
}
return count.intValue();
}
public void rollback() {
entityManager.getTransaction().rollback();
}
#SuppressWarnings("unchecked")
protected Class<E> getClassType() {
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
return (Class<E>) parameterizedType.getActualTypeArguments()[0];
}
#SuppressWarnings("unchecked")
public List<E> listarLazy(E pesquisa, int startingAt, int maxPerPage,
String sortField, String sortOrder) {
List<E> lista = new ArrayList<E>();
try {
Query q = entityManager.createQuery("FROM "
+ pesquisa.getClass().getName());
q.setFirstResult(startingAt);
q.setMaxResults(maxPerPage);
lista = q.getResultList();
} catch (Exception e) {
LOGGER.error("Erro ao buscar listagem Lazy", e);
}
return lista;
}
}
I'm a begginer on Spring Security, being so, any help is welcome, thanks
If I get this right, you want to use Spring Security for security and CDI for dependency injection.
In that case, you need to make sure that Spring and CDI don't try to manage the same beans. Even when you don't use Spring Core directly, you now have both Spring and CDI on your classpath. When Spring discovers javax.inject.Inject on its classpath, it will treat #Inject as synonymous to #Autowired and try to inject Spring beans into the annotated injection target.
That's why you get the exception - it's Spring and not CDI complaining about a missing bean.

How to get parent of a custom component?

I have a custom container component, that I want to use like this:
<p:a>A
<p:a>B</p:a>
</p:a>
That should generate this markup:
<div>A
<div>B</div>
</div>
Code for the component is below.
public class TagA extends TagHandler {
Logger logger = Logger.getLogger(getClass().getName());
public TagA(TagConfig config) {
super(config);
}
public void apply(FaceletContext ctx, UIComponent parent)
throws IOException {
UIComponentBase c = new UIComponentBase() {
public void encodeBegin(FacesContext ctx) throws IOException {
//getParent() always returns UIViewRot
logger.info("Parent is: " + getParent().getClass().getName());
ResponseWriter w = ctx.getResponseWriter();
w.write("<div>");
super.encodeBegin(ctx);
}
public void encodeEnd(FacesContext ctx) throws IOException {
ResponseWriter w = ctx.getResponseWriter();
w.write("</div>");
super.encodeEnd(ctx);
}
// abstract method in base, must override
public String getFamily() {
return "com.mobiarch.nf";
}
};
parent.getChildren().add(c);
nextHandler.apply(ctx, parent);
}
}
Unfortunately, this is rendering the following markup:
<div></div>A
<div></div>B
For others in a similar situation, just develop the component and not the tag.
#FacesComponent("my.ComponentA")
public class ComponentA extends UIComponentBase {
Logger logger = Logger.getLogger(getClass().getName());
public String getFamily() {
return "my.custom.component";
}
public void encodeBegin(FacesContext ctx) throws IOException {
super.encodeBegin(ctx);
logger.info("Component parent is: " + getParent().getClass().getName());
ResponseWriter w = ctx.getResponseWriter();
w.write("<div>");
}
public void encodeEnd(FacesContext ctx) throws IOException {
super.encodeEnd(ctx);
ResponseWriter w = ctx.getResponseWriter();
w.write("</div>");
}
}
Register it in your ??.taglib.xml
<tag>
<tag-name>a</tag-name>
<component>
<component-type>my.ComponentA</component-type>
</component>
</tag>

Resources