| ←Older revision |
Revision as of 04:53, 20 November 2009 |
| Line 40: |
Line 40: |
| | | | |
| | --[[User:JaroslavTulach|JaroslavTulach]] 08:46, 19 November 2009 (UTC) | | --[[User:JaroslavTulach|JaroslavTulach]] 08:46, 19 November 2009 (UTC) |
| | + | == btilford said ... == |
| | + | |
| | + | <div class='commentBlock'> |
| | + | I did a pretty bad job explaining how it works... ;) |
| | + | |
| | + | So basically someone could create a library with an annotation and an "Aspect" |
| | + | <source lang="java"> |
| | + | @Inherited |
| | + | @Documented |
| | + | @Target(ElementType.METHOD) |
| | + | @Retention(RetentionPolicy.RUNTIME) |
| | + | public @interface BoundProp { |
| | + | String value(); |
| | + | } |
| | + | </source> |
| | + | <source lang="java"> |
| | + | @Aspect |
| | + | @Component |
| | + | public class BoundPropertyAspect { |
| | + | |
| | + | private static final String SETTER = "^set"; |
| | + | //execution(public * *(..)) |
| | + | @Around( |
| | + | "@annotation(test.BoundProp) && execution(public * *..*.set*(*))") |
| | + | private void propertyChanged(ProceedingJoinPoint joinPoint) { |
| | + | Logger.getLogger(getClass().getName()).info("Advice propertyChanged"); |
| | + | |
| | + | SourceLocation source = joinPoint.getSourceLocation(); |
| | + | // Logger.getLogger(getClass().getName()).info("\tSource: " + source.getFileName() + " (" + source.getLine() + ")"); |
| | + | |
| | + | Object owner = joinPoint.getTarget(); |
| | + | Logger.getLogger(getClass().getName()).info("\tOwner: " + owner.getClass().getName()); |
| | + | |
| | + | Object newValue = joinPoint.getArgs()[0]; |
| | + | Logger.getLogger(getClass().getName()).info("\tnewValue: " + newValue.toString()); |
| | + | |
| | + | |
| | + | String setter = joinPoint.getSignature().getName(); |
| | + | Logger.getLogger(getClass().getName()).info("\tmethodName: " + setter); |
| | + | |
| | + | |
| | + | PropertyChangeSupport pcs = null; |
| | + | |
| | + | Object old = null; |
| | + | try { |
| | + | old = |
| | + | owner.getClass().getMethod( |
| | + | setter.replaceFirst(SETTER, "get")).invoke(owner); |
| | + | pcs = |
| | + | (PropertyChangeSupport) owner.getClass().getMethod( |
| | + | "getPropertyChangeSupport").invoke(owner); |
| | + | |
| | + | } catch (Throwable ex) { |
| | + | Logger.getLogger(BoundPropertyAspect.class.getName()).log( |
| | + | Level.SEVERE, |
| | + | null, ex); |
| | + | } finally { |
| | + | try { |
| | + | joinPoint.proceed(); |
| | + | } catch (Throwable ex) { |
| | + | Logger.getLogger(BoundPropertyAspect.class.getName()).log( |
| | + | Level.SEVERE, |
| | + | null, ex); |
| | + | } |
| | + | } |
| | + | if (pcs != null) { |
| | + | pcs.firePropertyChange(setter.replaceFirst(SETTER, ""), old, |
| | + | newValue); |
| | + | } |
| | + | |
| | + | |
| | + | } |
| | + | } |
| | + | </source> |
| | + | |
| | + | Then that aspect could be "triggered" by annotating a method with the @BoundProp annotation |
| | + | <source lang="java"> |
| | + | class SomeClass { |
| | + | @BoundProp |
| | + | void setSomething(Object singleArg) {...} |
| | + | } |
| | + | </source> |
| | + | |
| | + | --btilford 05:53, 20 November 2009 (CET) |
| | + | </div> |