Привет. Есть у меня самописный набор классов а-ля Java Beans, т.е.:
class DummyBean
{
private String m_str_prop;
private List<PropertyListener> m_listeners;
@PropertyAccessor
public String getStringProp()
{
return m_str_prop;
}
@PropertyAccessor
public void setStringProp(String a_str)
{
if(!m_str_prop.equals(m_str_prop = a_str))
{
// дергаем слушателей
firePropertyChangeEvent();
}
}
// ...
public void addPropertyListener(PropertyListener l)
{
// ...
}
public void firePropertyChangeEvent()
{
// ...
}
// далее код анализа свойств бина и доступа к ним по строковому ИД (см. пояснение)
}
Т.е. бин с одним свойством «StringProp» типа String, при изменении которого должны оповещаться слушатели. За последнее ответственен метод firePropertyChangeEvent(), который, как видно, не имеет информации о том, какое именно свойство было изменено (предположим таки, что свойств у нас более одного).
Задача сделать так, чтобы вышеупомянутый метод каким-то образом сообщал слушателям идентификатор события.
Внимательный ЛОРовец наверняка заметил аннотацию PropertyAccessor. Это велосипед, который позволяет занести свойства бина в мап, чтобы пользователь мог применить оба способа изменения свойства:
DummyBean db = new DummyBean();
db.setProperty("StringProp","new value"); // первый способ
db.setStringProp("new value"); // второй способ
Вся магия заключается в том, что класс бина через Reflection ищет у себя методы, помеченные аннотацией, и, разделяя эти методы на геттеры и сеттеры, а так же определяя имя свойства по имени метода, заносит все это в мап, чтобы пользователь мог воспользоваться «первым» из способов.
Напомню задачу, нужно чтоб слушатели события изменения свойства получали его идентификатор. Решение проблемы очевидно (с самого начала :) ):
...
@PropertyAccessor
public void setStringProp(String a_str)
{
if(!m_str_prop.equals(m_str_prop = a_str))
{
// дергаем слушателей
firePropertyChangeEvent("StringProp");
}
}
public void firePropertyChangeEvent(String a_prop_id)
{
// ...
}
...
Но это совершенно не круто, у нас могут быть десятки бинов, у каждого из которых пара десятков свойств, нехорошо заставлять программиста руками писать строковый ИД свойства в каждом сеттере, когда эта же информация уже есть в имени метода!
Извиняюсь за простыню, надеюсь доступно объяснил проблему, жду ваших вопросов/предложений по решению)
PS. Вот, например, есть вариант в методе firePropertyChangeEvent() определять имя вызывающего метода путем анализа стека. Но это совсем не красиво, кмк.
Еще можно использовать compile-time аннотации, чтобы компилятор дописывал ид события сам. Это труъ?