import java.io.*; import java.util.*; import java.lang.reflect.*; public class Beans { public static void main(String[] args) { new OK().f(); new NO().f(); } /* * Our classes */ interface Something {void f();} /** * Anyone can advise this guy */ static class OK implements Something { public void f() {System.out.println("ok");} } /** * No one can advise this guy */ static class NO implements Something { public void f() {System.out.println("no");} } /* * This is the aspect that will try to advise classes OK and NO */ static aspect Intervener { before(): execution(void *.f()) {System.out.println(thisJoinPoint);} } /* * Tries to detect nasty aspects by looking at the stack */ static aspect InterventionDiscoverer { static class InterventionException extends RuntimeException { InterventionException(String s) {super(s);} } /** * String(Class) -> Boolean * True if any methods in Class cls are true below */ static boolean isAspect(String cls) { try { Class c = Class.forName(cls); return isAspect(c.getMethods()) || isAspect(c.getDeclaredMethods()); } catch (Exception e) {throw new RuntimeException(e);} } /** * Method[] -> Boolean * True is one of ms has the string 'acj$' in it */ static boolean isAspect(Method[] ms) throws Exception { for (int i=0; i 2 // // we want to protect this class // && cs[2].equals("Beans$NO") // // we know *we* can advise this class // && !cs[1].equals(InterventionDiscoverer.class.getName()) // // check the class right above the NO object // && isAspect(cs[1])) { String msg = "\nAspect " + cs[1] + " can't advice the class NO:\n" + os.lines; throw new InterventionException(msg); } } } /* -------------------------------------------------- * Don't worry about thing below this line * -------------------------------------------------- */ static class MyOutputStream extends OutputStream { final List lines = new ArrayList(); private StringBuffer sb = new StringBuffer(); public void write(int b) throws IOException { char c = (char)b; if (c == '\n') { lines.add(sb = new StringBuffer()); } else { sb.append(c); } } String[] classes() { String[] cs = new String[lines.size()-1]; for (int i=0; i