how can we apply aspect oriented programming on a particular line of java class ? - aspectj

How can we apply aop on the last line of main method ?
Below is a test class for call by value in java. I have been asked in one interview to apply Aspect oriented programming on last line of the class. Is it possible to apply AOP on a particular line of any java class, if yes then please give some example code.
public class TestCallByValue {
public static void main(String[] args) {
Student st = new Student("Sanjeev", 1);
changeName(st);
System.out.println(st.getName());//apply aop on this line to stop printing sysout
}
public static void changeName(Student st) {
st = new Student("Rajeev", 2);
st.setName("Amit");
}
}
class Student {
String name;
Integer id;
public Student(String name, Integer id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

What can be applied on a particular line of java code is called a joinpoint
This link lists the possible joinpoints you can set in your code, with aspectj. As you can see, only constructor call, method call, field initialization, etc. can be defined as joinpoints
The only way is to apply a pointcut on System.out#println. You could as well encapsulate System.out.println(st.getName()); in a dedicated method

AspectJ doesn't operate on source code, it operates on the semantic structure of Java programs. As such, it doesn't have a concept of "lines". The interviewer meant that you should prevent a particular method call from happening, and told you where that method call is, in this particular case it's the last statement of the main method.
This statement is located in TestCallByValue.main() method and invokes println() on System.out, which is a PrintStream. While we cannot indicate to AspectJ that we want to prevent only the "last" statement from executing, we can narrow this down to
method calls to the println method of the PrintStream class, accepting a String and returning void, within the code contained in the TestCallByValue.main() method that accepts an array of Strings and returns void
To prevent the method call from happening, you will need an around advice which doesn't call proceed(). We can also check whether the target of the method call is actually System.out, so we prevent only System.out.println(String), not println(String) calls on other instances of PrintStream.
The above can be achieved with the following aspect:
aspect DummyAspect {
pointcut printlnStatementInMain(): withincode(void TestCallByValue.main(String[]))
&& call(void java.io.PrintStream.println(String));
void around(): printlnStatementInMain() {
if (thisJoinPoint.getTarget() != System.out) {
proceed();
}
}
}

Related

Is it possible to pass arguments in the expression of a PropertyModel?

I have a model object that has a getter/setter that accepts a String.
public String getStringValue(String key)
I need to know if it is possible to use that getter with a PropertyModel and if so how do I do it? An example might look something like this:
new PropertyModel<String>(myObj, "StringValue[key]");
There isn't built in way to do it. But you can define your own Wicket Model to do it via reflection.
For example:
public class FunctionReflectionReadOnlyModel<T, R> extends AbstractReadOnlyModel<T> {
private Object object;
private String functionName;
private R key;
private Class<R> keyClass;
public FunctionReflectionReadOnlyModel(Object object, String expression, Class<R> keyClass) {
this.object = object;
this.functionName = getFunctionName(expression);
this.key = getKey(expression);
this.keyClass = keyClass;
}
#Override
public T getObject() {
try {
Method method = object.getClass().getMethod(functionName, keyClass);
return (T)method.invoke(object, key);
} catch (Exception ex) {
//process exception
return null;
}
}
}
You just need implement getFunctionName(String expression) and getKey(String expression) on your needs.
But I think that is better use another variant. It's not particularly what you ask, but it is typified. Also required Java 8.
public class FunctionWithKeyReadOnlyModel<T, R> extends AbstractReadOnlyModel<T> {
private Function<R, T> function;
private R key;
public FunctionWithKeyReadOnlyModel(Function<R, T> function, R key) {
this.function = function;
this.key = key;
}
#Override
public T getObject() {
return function.apply(key);
}
}
And then you can use it like this:
new FunctionWithKeyReadOnlyModel(obj::getStringValue, "key");
I've read about usage only PropertyModel too late. In this case you can inherit your class from PropertyModel and change getModel/setModel like in example FunctionReflectionReadOnlyModel. So you don't need change other classes API. But if you want all features of PropertyModel (nested objects) you need implement it.
As answered by #merz this is not supported by Wicket's PropertyModel, actually by PropertyResolver.
PropertyResolver supports such access if you use a java.util.Map:
public Map<String, String> getProperty() {return theMap;}
Check org.apache.wicket.core.util.lang.PropertyResolver's javadoc.

Overriding Getters and Setters in tinkerpop Frames annotated model

I'm working on a new piece of software and I'd like the values in the database to be encrypted. We are using OrientDB and are trying to implement the project using the tinkerpop libraries. Here I'm stuck a little bit.
For one function, I need to pull a list of all vertices of a type and return them. I have my annotated interface for the person object, and I added methods to encrypt and decrypt necessary fields right now. But when I decrypt them, it persists the decrypted values back to the database.
Is there a way to either override the getters and setters to handle the encryption/decryption at that point or do I need to detach the models from the db before performing my decryption?
Here's my code for my interface:
public interface iPerson {
#Property("firstName")
public void setFirstName(String firstName);
#Property("firstName")
public String getFirstName();
#Property("lastName")
public String getLastName();
#Property("lastName")
public void setLastName(String lastName);
#Property("id")
public String getId();
#Property("id")
public void setId(String id);
#Property("dateOfBirth")
public String getDateOfBirth();
#Property("dateOfBirth")
public void setDateOfBirth(String dateOfBirth);
#JavaHandler
public void encryptFields() throws Exception;
#JavaHandler
public void decryptFields() throws Exception;
public abstract class Impl implements JavaHandlerContext<Vertex>, iPerson {
#Initializer
public void init() {
//This will be called when a new framed element is added to the graph.
setFirstName("");
setLastName("");
setDateOfBirth("01-01-1900");
setPK_Person("-1");
}
/**
* shortcut method to make the class encrypt all of the fields that should be encrypted for data storage
* #throws Exception
*/
public void encryptFields() throws Exception {
setLastName(Crypto.encryptHex(getLastName()));
setFirstName(Crypto.encryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.encryptHex(getDateOfBirth()));
}
}
/**
* shortcut method to make the class decrypt all of the fields that should be decrypted for data display and return
* #throws Exception
*/
public void decryptFields() throws Exception {
setLastName(Crypto.decryptHex(getLastName()));
setFirstName(Crypto.decryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.decryptHex(getDateOfBirth()));
}
}
}
}
(I assume) Data is persisted to the database when a Vertex's property is set. If you want to store encrypted values in the database, then you need to ensure the value is encrypted when the property is set.
If you want to override the default behaviour of the #Property getter/setter methods (so that you can add en/decryption), I'd recommend using a custom handler (e.g. #JavaHandler).
For example:
IPerson
#JavaHandlerClass(Person.class)
public interface IPerson extends VertexFrame {
#JavaHandler
public void setFirstName(String firstName);
#JavaHandler
public String getFirstName();
}
Person
abstract class Person implements JavaHandlerContext<Vertex>, IPerson {
#Override
void setFirstName(String firstName) {
asVertex().setProperty('firstName', encrypt(firstName))
}
#Override
String getFirstName() {
return decrypt(asVertex().getProperty('firstName'))
}
static String encrypt(String plain){
return plain.toUpperCase(); // <- your own implementation here
}
static String decrypt(Object encrypted){
return encrypted.toString().toLowerCase(); // <- your own implementation here
}
}
Usage example (Groovy)
// setup
IPerson nickg = framedGraph.addVertex('PID1', IPerson)
IPerson jspriggs = framedGraph.addVertex('PID2', IPerson)
nickg.setFirstName('nickg')
jspriggs.setFirstName('jspriggs')
// re-retrieve from Frame vertices sometime later...
IPerson nickg2 = framedGraph.getVertex(nickg.asVertex().id, IPerson)
IPerson jspriggs2 = framedGraph.getVertex(jspriggs.asVertex().id, IPerson)
// check encrypted values (these are stored in the DB)...
assert nickg2.asVertex().getProperty('firstName') == 'NICKG'
assert jspriggs2.asVertex().getProperty('firstName') == 'JSPRIGGS'
// check decrypted getters...
assert nickg2.getFirstName() == 'nickg'
assert jspriggs2.getFirstName() == 'jspriggs'
If using Groovy, you could intercept calls to these methods programatically (which would be nice because you could keep using #Property annotations).
I'm not sure if there's a Tinkerpop solution to intercepting these calls, other than writing your own custom handler (maybe try extending the JavaHandlerModule?).
Thanks for the comment, and I should have gotten back to respond to this sooner, but I recently found a better answer to my problem. I was looking for a way to make the encrypt/decrypt happen without overhead and without developers really noticing it happens.
The better way to tackle this issue was actually to write hooks for before insert/update and after read to handle it just at the database layer. I was able to write it in java, package a jar file for it and install it on our orientDB instance, picked up pretty flawlessly and helped us to encrypt the necessary fields without noticing any speed decreases.

How to mock #PrePersist method?

How do I mock a #PrePersist method, e.g. preInit(), of an entity that I instantiate?
I'm using TestNG. EasyMock is prefered.
#Test(enabled = true)
public void testCreateOrder() {
// Instantiating the new mini order will automatically invoke the pre-persist method, which needs to be mocked/overwritten!
MiniOrder order = new MiniOrder();
order.setDate(new Date());
order.setCustomerId(32423423);
}
The MiniOrder.java is an entity that has a pre-persist method. Again, the one I like to mock/overwrite. E.g. this.id = 1; Alternatively one could also mock the IdGenerator.getNewId() method.
#PrePersist
protected void preInit(){
this.id = IdGenerator.getNewId();
}
I don't want the IdGenertor class to be called, because it attempts to grab a jndi resource. I just don't understand how to capture this pre-persist method in advance, so that it's not triggered ,respectively replaced by different code, before the object is fully instantiaded.
In this case, what you really want is to mock the IdGenerator dependency, which happens to be called from a #PrePersist method.
Using JMockit, the test can be written as follows:
#Test
public void createOrder()
{
new MockUp<IdGenerator>() {
// change as needed...
#Mock int getNewId() { return 123; }
};
MiniOrder order = new MiniOrder();
order.setDate(new Date());
order.setCustomerId(32423423);
}

How should I design a game character class with a large number of attributes?

I am a student who is currently learning Java and trying to write a small text-based RPG game with it. The first problem I encountered in the design of the game is the 'character' class, which represents all the playable heroes and enemy characters, and is now implemented by myself as the following:
class RPGActor {
private String name;
private int HP; // hit points
private int MP; // mana
private int AP; // attack
private int DP; // defense
... // followed by tens of other attributes.
public Actor(int actorID)
{
... // Reads all attributes from a file based on the 'actorID'.
}
public void printStatus()
{
System.out.println(name);
System.out.println("HP :" + HP);
System.out.println("MP :" + MP);
... // And print all the attributes one by one.
}
public void setHP(int newHP)
{
HP = newHP;
}
public int getHP()
{
return HP;
}
public void setMP(...)
{
...
}
// And tens of accessors and mutators for each attribute
}
The problem I see with this design is that there are too many things that needs to be hand-coded: There are some 20-30 attributes in the class, and a separate accessor/mutator needs to be implemented for each of them. And the function for displaying the current status of the hero, printStatus, must output each attribute separately even though every line of output follows the exact same format. This makes the class definition tediously long.
Plus, if later I want to add one more attribute to the game, then I must remember to modify 'printStatus', and add a pair of accessor/mutator for it.
So my question is: is there a way to design the class so that I can use ONE pair of set/get functions to set all attributes. Something like:
public void set(String attribName, int attribVal)
{
...
}
and print the attributes iteratively like this:
public void printStatus()
{
System.out.println(name);
for (...)
System.out.println(curAttribName + ": " + curAttribVal);
}
Thank you very much!
I'll show you a solution, to set all attributes with one method, but you shouldn't use it, I'll tell you the reasons afterwards.
class RPGActor {
private static final String NAME = "Name";
private static final String HP = "HP";
private static final String MP = "MP";
private static final String AP = "AP";
private static final String DP = "DP";
// ... followed by tens of other attributes.
private Map<String, Object> attributes = new HashMap<String, Object>();
public RPGActor(int actorID) {
this.attributes.put(NAME, nameFromFile);
// ... Reads all attributes from a file based on the 'actorID'.
}
public void setAttribute(String attributeName, Object value) {
this.attributes.put(attributeName, value);
}
public int getAttribute(String attributeName) {
return this.attributes.get(attributeName);
}
}
This has several disadvantages:
no code-completion for setting specific attributes
less readable
...
BETTER:
Although you are using classes and objects, this isn't very object-oriented. Especially you're violating the encapsulation paradigm.
You shouldn't set the HP explicitly from outside the class itself. Only in rare use cases that is needed. Instead you should think about what the actor really does: attacking, defending, casting spells.
Therefore it should look more like this:
class RPGActor {
private String name;
private int HP; // hit points
private int MP; // mana
private int AP; // attack
private int DP; // defense
// ... followed by tens of other attributes.
private Map<String, Object> attributes = new HashMap<String, Object>();
public RPGActor(int actorID) {
// ... Reads all attributes from a file based on the 'actorID'.
}
public void attacks(RPGActor defender) {
defender.defend(this.getAttack());
}
public void defend(Attack attack) {
switch (attack.getType()) {
case PHYSICAL:
// This actor is resistant against physical attacks.
return;
case MAGICAL:
this.HP = this.HP - attack.getStrength();
break;
}
}
public void castSpell(Spell spell, Set<Target> targets) {
// targets could be other actors, equipment or chickens dependent on the spell
// ...
}
}
With inheritance or more advanced design patterns like the Strategy pattern you can make each actor react differently on attacks.

Forcing the use of a specific overload of a method in C#

I have an overloaded generic method used to obtain the value of a property of an object of type PageData. The properties collection is implemented as a Dictionary<string, object>. The method is used to avoid the tedium of checking if the property is not null and has a value.
A common pattern is to bind a collection of PageData to a repeater. Then within the repeater each PageData is the Container.DataItem which is of type object.
I wrote the original extension method against PageData:
public static T GetPropertyValue<T>(this PageData page, string propertyName);
But when data binding, you have to cast the Container.DataItem to PageData:
<%# ((PageData)Container.DataItem).GetPropertyValue("SomeProperty") %>
I got a little itch and wondered if I couldn't overload the method to extend object, place this method in a separate namespace (so as not to pollute everything that inherits object) and only use this namespace in my aspx/ascx files where I know I've databound a collection of PageData. With this, I can then avoid the messy cast in my aspx/ascx e.g.
// The new overload
public static T GetPropertyValue<T>(this object page, string propertyName);
// and the new usage
<%# Container.DataItem.GetPropertyValue("SomeProperty") %>
Inside the object version of GetPropertyValue, I cast the page parameter to PageData
public static T GetPropertyValue<T>(this object page, string propertyName)
{
PageData data = page as PageData;
if (data != null)
{
return data.GetPropertyValue<T>(propertyName);
}
else
{
return default(T);
}
}
and then forward the call onto, what I would expect to be PageData version of GetPropertyValue, however, I'm getting a StackOverflowException as it's just re-calling the object version.
How can I get the compiler to realise that the PageData overload is a better match than the object overload?
The extension method syntax is just syntactic sugar to call static methods on objects. Just call it like you would any other regular static method (casting arguments if necessary).
i.e.,
public static T GetPropertyValue<T>(this object page, string propertyName)
{
PageData data = page as PageData;
if (data != null)
{
//will call the GetPropertyValue<T>(PageData,string) overload
return GetPropertyValue<T>(data, propertyName);
}
else
{
return default(T);
}
}
[edit]
In light of your comment, I wrote a test program to see this behavior. It looks like it does go with the most local method.
using System;
using Test.Nested;
namespace Test
{
namespace Nested
{
public static class Helper
{
public static void Method(this int num)
{
Console.WriteLine("Called method : Test.Nested.Helper.Method(int)");
}
}
}
static class Helper
{
public static void Method(this object obj)
{
Console.WriteLine("Called method : Test.Helper.Method(object)");
}
}
class Program
{
static void Main(string[] args)
{
int x = 0;
x.Method(); //calls the object overload
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
Console.WriteLine();
}
}
}
To make sure the nesting is not affecting anything, tried this also removing the object overload:
using System;
using Test.Nested;
namespace Test
{
namespace Nested
{
public static class Helper
{
public static void Method(this int num)
{
Console.WriteLine("Called method : Test.Nested.Helper.Method(int)");
}
}
}
static class Helper
{
public static void Method(this string str)
{
Console.WriteLine("Called method : Test.Helper.Method(string)");
}
}
class Program
{
static void Main(string[] args)
{
int x = 0;
x.Method(); //calls the int overload
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
Console.WriteLine();
}
}
}
Sure enough, the int overload is called.
So I think it's just that, when using the extension method syntax, the compiler looks within the current namespace first for appropriate methods (the "most local"), then other visible namespaces.
It should already be working fine. I've included a short but complete example below. I suggest you double-check your method signatures and calls, and if you're still having problems, try to come up with a similar short-but-complete program to edit into your question. I suspect you'll find the answer while coming up with the program, but at least if you don't, we should be able to reproduce it and fix it.
using System;
static class Extensions
{
public static void Foo<T>(this string x)
{
Console.WriteLine("Foo<{0}>(string)", typeof(T).Name);
}
public static void Foo<T>(this object x)
{
Console.WriteLine("Foo<{0}>(object)", typeof(T).Name);
string y = (string) x;
y.Foo<T>();
}
}
class Test
{
static void Main()
{
object s = "test";
s.Foo<int>();
}
}