Yes, but that solution requires specific
knowledge of the field you are pointcutting on. In general, I need to
write one pointcut that services many objects with many different fields.
Otherwise I might as well manually inline my undo / transaction
rollback facility.
-pete
On 9/14/06, Vincent Jorrand <vjorrand@xxxxxxxxx >
wrote:
Matthew Webster's post actually mentions 2 solutions, one of
which uses a priviledged aspect and no reflection.
The following is
copied from his post:
public class SomeClass {
private int intField;
public void setInt
(int i) {
intField =
i;
}
}
public privileged aspect
PrivilegedAspect {
pointcut intFieldSet(SomeClass
obj, int newValue) :
set(*
intField) && target(obj) && args(newValue)
&& withincode(*
SomeClass+.set*(..))
;
before (SomeClass obj, int newValue)
: intFieldSet (obj,newValue) {
int oldValue = obj.intField;
System.out.println("?
beforeIntFieldSet() oldVaue=" + oldValue
+
", newValue=" + newValue);
}
}
Vincent
----- Original Message ----
From: Peter Murray <pete@xxxxxxxxxxxx
>
To: aspectj-users@xxxxxxxxxxx
Sent: Thursday, September
14, 2006 5:12:00 PM
Subject: Re: [aspectj-users] Question re: declare
error
I wonder if there would be support in the AspectJ community for
adding an additional "argument" to the set property that could optionally be
bound using syntax like
... set(* *) && args(newValue,
oldValue) ...
which would send in the old value?
Any
thoughts? Am I off in the weeds - or is this technically possible if
we expand the definition of the set joinpoint?
-pete
peter m.
murray
pete@xxxxxxxxxxxx
On 9/14/06, Ron Bodkin
<
rbodkin@xxxxxxxxxxxxxx> wrote:
Hi Peter: the topic
of getting old values of a field during set has come up before on the
mailing list and as you've determined the only way to do it where you advise
different fields is via reflection (e.g., see Matthew Webster's post at
http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg04126.html
). I see how
the obfuscator might break with reflective code (though I'd hope that an
obfuscator wouldn't: lots of libraries now rely on reflection). One idea
might be to track the old value of the field also in advice so you can
compare the previous value to the current value (e.g., using your map that
associates static parts with state).
Ron,
Thanks a bunch! That does the
trick. I was suspicious that there might be an operator for
"subtypes".
Now, the real question is - how can I get ahold of the
original value of a field during around set advice so I can use AspectJ to
create the ValueChange objects and post them based on the @Transactional
annotation. It seems the only way is through reflection which will
break once we obfuscate...
Any thoughts on
that?
Cheers,
pete
peter m. murray
pete@xxxxxxxxxxxx
I would use
within(Change+) instead of this(Change). That isn't the exact same semantics
as using this (*) but in most cases it would capture your intent: it makes
it an error to set the field outside of code that's in a subtype of
Change.
(*) it's based on
the join points being lexically located inside Change. So it can differ
because it won't allow setting the fields in a base class that might be
extended by a type that extends Change. It also doesn't allow for setting
inside of inter-type declared methods (you could extend the rule to allow
those if that matters to you).
Subject: Re:
[aspectj-users] Question re: declare error
Thanks
for your reply, Elizabeth.
That makes sense - do you see a way to
accomplish what I am trying to do?
Cheers,
pete
peter m.
murray
pete@xxxxxxxxxxxx
As I understand it,
declare is a compile time error or warning; this(), target() and args() are
all run time checks. Except in the simplest of cases, it is not possible to
tell at compile time what the type of this, target or args will
be.
I'd
like to declare an error if my @Transactional attributed instance variables
are being set outside of the context of a Change object. In other
words, I'd like to have an error in this case:
public class
Foo
{
@Transactional
String
name
public void setName(String
newName)
{
name = newName;
}
}
But not in this
case:
public class Foo
{
@Transactional
String name
public void setName(String
newName)
{
new ValueChange<String>(name, newName)
{
public void set(String value)
{
name = value;
}
}.post();
}
}
It seems
like this kind of aspect should do that:
public aspect
FieldChangeAspect
{
declare error :
set(@Transactional * *) &&
!this(Change) : "Set of @Transactional variable not in Change
object";
}
But this gives me an error saying "this() pointcut
designator cannot be used in declare statements." BTW, target(),
and args() also give the same error for declare statements i guess, so you
can't filter on types of this, target, or args in declares.
Am I
missing something? Is there a reason for this or could these be
enhancements?
Cheers,
--
-pete
peter m. murray
pete@xxxxxxxxxxxx
CONFIDENTIAL AND PRIVILEGED
INFORMATION NOTICE
This e-mail, and any attachments, may
contain information that is confidential, subject to copyright, or
exempt from disclosure. Any unauthorized review, disclosure,
retransmission, dissemination or other use of or reliance on this
information may be unlawful and is strictly prohibited.
|
AVIS
D'INFORMATION CONFIDENTIELLE ET PRIVIL�GI�E
Le pr�sent courriel, et
toute pi�ce jointe, peut contenir de
l'information qui est
confidentielle, r�gie par les droits
d'auteur, ou interdite de divulgation. Tout
examen,
divulgation, retransmission, diffusion ou autres utilisations
non
autoris�es de l'information ou d�pendance non autoris�e
envers celle-ci
peut �tre ill�gale et est strictement interdite.
_______________________________________________
aspectj-users
mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users