Templates and VC++ event handling and generics

The difference between templates and generics is a hotly debated topic. I am trying to understand all of this and Bruce Eckel recently wrote about a form of ‘Curiously Recurring Template Pattern’ in his blog.

Let us look at Java code that uses this pattern


public class PropertySupportAspect<T extends PropertySupportAspect> {

PropertyChangeSupport support = new PropertyChangeSupport (this);

//Other methods are not shown

public void firePropertyChange( String property,
String oldval,
String newval) {
support.firePropertyChange( property,
( oldval == null ) ?
oldval :
new String(oldval),
new String(newval));
}
}
class Bean extends PropertySupportAspect{
private String name;

public String getName() {
return name;
}
public void setName( String name ) {
firePropertyChange( "name",
getName(),
name );
this.name = name;
}
}

Since ‘CRTP’ is usually associated with C++ templates I decided to try the same code with similar functionality using VC++.

This is what I could manage with VC++.

#include

template<T>
class PropertyChangeListener {
public:
void propertyChange( std::string oldValue, std::string newValue ) {
printf("Changed from " + oldValue + " to " + newValue );

}

void hookEvent(T* bean) {
__hook(&T::MyEvent, bean, &PropertyChangeListener::propertyChange);
}

void unhookEvent(T* bean) {
__unhook(&T::MyEvent, bean, &PropertyChangeListener::propertyChange);
}
};

class Bean : public PropertyChangeListener {
std::string name;
typedef PropertyChangeListener listener;

public:
__event void MyEvent(std::string value);

public:
void setName( std::string name ){
listener::hookEvent(this);
__raise this->MyEvent( name );
}
};

int main() {
Bean bean;
bean.setName( "Test" );
}

This code does not compile because methods ‘hookEvent’ and ‘unhookEvent’ have a problem. I tried the VC++ forum and I will update if there is a solution. I myself don’t have experience with VC++.

Update :
I corrected my code error based on the reply I received from the VC++ team in the MSDN forum. I hadn’t noticed the description of these errors.

1. C3713: ‘PropertyChangeListener::propertyChange’: an event handler method must have the same function parameters as the source ‘Bean::MyEvent’

class Bean : public PropertyChangeListener {
std::string name;
typedef PropertyChangeListener listener;

public:
__event void MyEvent(std::string oldValue, std::string newValue);

public:
void setName( std::string name1 ){
listener::hookEvent(this);
__raise this->MyEvent( name, name1 );
}
};

1. C3740: ‘PropertyChangeListener’: templates cannot source or receive events

Quote from the team:
We don’t support templates both in event source and event receiver. You can not hook an event to a member template function. Further more, we might cut Native Event support entirely in the future release. We really encourage you to write your own event codes.

First AOP use case

My first real AOP use case uses Java 5 annotations and AspectWerkz 2.0. I use AspectWerkz because I can look at their Java source code and I could use Pointcuts to pick out Java 5 annotations. At this point I don’t combine Generics and AOP. I wanted to show a status message only if particular methods were called. This is done so that the status is more accurate. The user will know the exact status at any point in time.

My annotation is

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE,
       ElementType.METHOD })
public @interface StatusShow {

 public String message();
}

I annotate like this
    @StatusShow( message=”Select diagram” )

I use Java reflection to get the argument to the annotation and print in the
status bar.
@Aspect(“perJVM”)
public class StatusReportAspect {
 
 @Expression(“execution(@com.blueprint.util.annotation.StatusShow * *..*(..))”)
    Pointcut statusMethods;

 @Before(“statusMethods”)
 public void before( final StaticJoinPoint sjp, final JoinPoint jp ) {
  try{
   Class<PaperSheet> clazz = PaperSheet.class;
   Method method = clazz.getMethod( sjp.getSignature().getName(),
                                                                  Graphics2D.class);
   if( method.isAnnotationPresent( StatusShow.class )){
    BluePrint.getStatus().
      setText( method.getAnnotation( StatusShow.class ).
                   message() );
   }
  }catch( Throwable t ){
   t.printStackTrace();
   //This is benign. Just ignore.
  }
 }
}

AOP Pointcut Matcher

This bug entry is about creating a PointCut matcher tool that would help us learn the AspectJ PointCut syntax.

An example is Groovy that helps us prototype using its console. See a previous entry about this.

AOP syntax problem

I have been trying to use AOP for a few months. One problem that I face is the syntax. I started with AspectWerkz. When they added support for JDK 5.0 I learnt to use that syntax. I am learning aspectj after they merged with it. Now AspectJ is introducing JDK 5 syntax. It is getting
more difficult with the introduction of generics support.

Though JDK 5 didn’t make it simpler, it seems that the syntax of different AOP frameworks is making the adoption harder. Sometimes it is difficult to keep track of what is in what version.

I have rewritten my AOP code using AspectJ 5 syntax after I
read this article


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class StatusReportAspect {

@Pointcut("execution(@com.blueprint.util.annotation.StatusShow * *..*(..))")
void statusMethods(){};

@Before("statusMethods()")
public void before( final JoinPoint jp ) {
try{
Class clazz = PaperSheet.class;
Method method = clazz.getMethod(
jp.getSignature().getName(),
Graphics2D.class);
if( method.isAnnotationPresent(
StatusShow.class )){

BluePrint.getStatus().setText(
method.getAnnotation( StatusShow.class ).
message() );
}
}catch( Throwable t ){
t.printStackTrace();
//This is benign. Just ignore.
}
}
}