Aspectj : getting the #Pointcut details in #Aspect - aspectj

I have an aspect that is called for any of the pointcuts defined, similar to something like this:
#Around("pointcut1(request) || pointcut2(request) || pointcut3(request)")
public ModelAndView myAspect(ProceedingJoinPoint proceedingJp,
HttpServletRequest request)
{
//do something.
}
So inside this aspect, I need to know that for which pointcut (pointcut1/2/3) this myAspect is called. Is there any why I can get this in aspect?
To add more details .....
Isn't there any parameter that I can get in #Aspect (method). I know I can get JoinPoint , but it doesn't work well for me.
Something like this would be very convenient....
#Around("pointcut1(request) || pointcut2(request) || pointcut3(request)")
public ModelAndView myAspect(ProceedingJoinPoint proceedingJp, PointCut pc ,HttpServletRequest request){
if (pc.equals("pointcut1")) {
//do something.
}
if (pc.equals("pointcut2")) {
//do something.
}
// ...
}
Please suggest !!
Any more suggestions please !!!

The best way to do this is to write advice for each of the component pointcuts and set a flag saying that it has been reached. Due to Aspect precedence (ie- which advice runs before which other advice), you need to ensure that the component advice is lexically above the final around advice. It will look like this:
boolean pointcut1Reached = false;
ModelAndView around(HttpServletRequest request) : pointcut1(request) {
pointcut1Reached = true;
try {
proceed(request);
} finally {
pointcut1Reached = false;
}
}
// ... similar for other pointcuts
#Around("pointcut1(request) || pointcut2(request) || pointcut3(request)")
public ModelAndView myAspect(ProceedingJoinPoint proceedingJp, HttpServletRequest request){
if (pointcut1Reached) {
//do something.
}
if (pointcut2Reached) {
//do something.
}
// ...
}
Two things to note here:
If your program is multithreaded, then you are going to need to ensure that the instantiation of the aspect is appropriate.
I use code style AspectJ syntax because I have a personal bias against annotation style. :)
To avoid the problems of multithreaded code, you can specify an instantiation model for the aspect.
aspect MyAspect percflowbelow( execution ( * * HttpServletRequest.something(..) ) { ... }
The statement above says that there will be one instance of the aspect instantiated for each cflow below a call to HttpServletRequest.something(). If one of the advice is reached inside the aspect, but it is not in the percflowbelow, then the advice will not be run.
The only trick now is to figure out what kind of pointcut should be placed inside of percflowbelow. Is there some method call way up in the stack that contains all of the pointcuts?
Once you have this figured out, you do not need to worry about multithreading.

Related

OOP avoid unnecessary repeated calls

so I have a question on OOP class design. I have read that we should "Tell, don't ask" and not use Exceptions for "Flow control". However in this particular case I see some redundant code being executed!
Lets assume Person have a list of events that he will be attending, and it must be enforced that he cannot attend an event that overlaps with his current schedule. So I have the following Java code
public class Person {
// this arraylist of events must not have overlapping events!
ArrayList<Events> eventsToAttend;
// checks if a person is free to attend a new event by viewing all events he is attending
public boolean canAttendEvent(Event newEvent) {
for(int i = 0; i < eventsToAttend.size(); i++) {
if (newEvent.isSameDayAndTime(eventsToAttend.get(i))) {
return false;
}
}
return true;
}
public void attendEvent(Event newEvent) {
// enforce the validity of the newEvent
if (!canAttendEvent(newEvent)) {
// throw exception and return
}
eventsToAttend.add(newEvent);
}
public static main(String[] args) {
// just an example usage!
Person person = somePersonWithEventsAlready;
Event event = new Event();
if (person.canAttendEvent(event)) {
// !!!
// Notice that canAttendEvent() is called twice!! how do you prevent this?
// !!!
person.attendEvent(event);
}
// Alternatively I could just try - catch around person.attendEvent(), but is that bad practise?
}
}
The issue I am facing in general with this way of doing things, is that "canAttendEvent()" is being called twice. However it is good practice according to OOP design patterns?
What would be a better way to do something like this? Thank you for reading this.
try - catch in the main is the best way to achieve what you are trying to avoid: call twice the function canAttendEvent

Laravel 5.4 FormRequest forbiddenResponse() method has been replaced by failedAuthorization()

As precised in the title, I noticed that the forbiddenResponse() method has been removed from the FormRequest in Laravel 5.4.
This method has been replaced by the failedAuthorization() method that now triggers an AuthorizationException.
This causes me troubles because I would need to make redirections from the form request and it seems that it is not possible anymore.
Would anybody have a solution in this way ?
Go to App\Exceptions\Handler and add this inside the render method:
if ($exception instanceof AuthorizationException) {
// Do what you want here, Response, Redirect...
}
Sorry for the delay, I became a father since my last message ;)
Here is what I have done since you gave me your tip.
I created a BaseRequest class that my formRequests extends. In it, I have override the failedAuthorization method like that :
protected function failedAuthorization()
{
$exception = new AuthorizationException('This action is unauthorized.');
$exception->error_message = $this->error_message;
$exception->redirect = $this->getRedirectUrl();
$exception->dontFlash = $this->dontFlash;
throw $exception;
}
In the App\Exceptions\Handler class, I have added the following treatment in the render method :
if ($exception instanceof AuthorizationException) {
// ajax or api call
if ($request->expectsJson()) {
// treatment
}
// we notify the current user with a modal
if($exception->error_message) Modal::alert($exception->error_message, 'error');
if ($exception->redirect){
return redirect()->to($exception->redirect)->withInput(request()->except($exception->dontFlash));
} else {
return redirect()->back()->withInput(request()->except($exception->dontFlash));
}
}
With this process, I have a satisfying treatment with a customizable formRequest use. But I still find that it is a bit messy and not really clean. If you or someone else has a better way to implement this, I would be glad to discuss it with you.

Can execute question using delegate commands in prism

This seems like a dumb question but I have looked through the docs for prism and searched the internet and can't find an example... Here is the deal.
I am using a DelegateCommand in Prism, it is working fine except when I assign a delegate to the can execute to the CanExecute method. in another view model I have a event that takes a bool that I am publishing too and I can see that the event is firing and that the bool is getting passed to my view model with the command in it no problem but this is what I don't understand... How does can execute know that the state has changed? Here is some code for the example.
from the view models ctor
eventAggregator.GetEvent<NavigationEnabledEvent>().Subscribe(OnNavigationEnabledChange, ThreadOption.UIThread);
NavigateCommand = new DelegateCommand(OnNavigate, () => nextButtonEnabled);
Now - here is the OnNavigationEnableChange event.
private void OnNavigationEnabledChange(bool navigationState)
{
nextButtonEnabled = navigationState;
}
enter code here
Like - I am totally missing something here - how does the command know that nextButtonEnabled is no true?
If someone could point me to a working example that would be awesome.
OK - thanks!
This is why I don't use the implementation of DelegateCommand in Prism. I've always hated the callback-based approach for enabling/disabling commands. It's entirely unnecessary, and as far as I can tell, its only (and rather doubtful) 'benefit' is that it's consistent with how execution itself is handled. But that has always seemed pointless to me because execution and enabling/disabling are clearly very different: a button knows when it wants to execute a command but doesn't know when the command's status might have changed.
So I always end up writing something like this:
public class RelayCommand : ICommand
{
private bool _isEnabled;
private Action _onExecute;
public RelayCommand(Action executeHandler)
{
_isEnabled = true;
_onExecute = executeHandler;
}
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
}
public bool CanExecute(object parameter)
{
return _isEnabled;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_onExecute();
}
}
(If necessary you could modify this to use weak references to execute change event handlers, like Prism does.)
But to answer your question: how is the callback approach even meant to work? Prism's DelegateCommand offers a RaiseCanExecuteChanged method you can invoke to ask it to raise the event that'll cause command invokers to query your command's CanExecute. Given that you have to tell the DelegateCommand any time your enabled status changes, I don't see any meaningful benefit of a callback-based approach. (Sometimes you see a broadcast model though - arranging so that any change in status anywhere notifies all command invokers! In that case, a callback is useful because it means it doesn't matter if you don't know what actually changed. But requerying every single command seems unpleasant to me.)
Answering your question how does the command know that it is now enabled:
NavigateCommand = new DelegateCommand(OnNavigate, () => nextButtonEnabled);
This overload of the DelegateCommand constructor takes 2 parameters:
The first is the command action and the second is the CanExecute delegate that returns bool.
in your example your CanExecute action always returns nextButtonEnabled
eventAggregator.GetEvent<NavigationEnabledEvent>().Subscribe(OnNavigationEnabledChange, ThreadOption.UIThread);
triggers OnNavigationEnabledChange that changes nextButtonEnabled
this is how it works...

How do I simplify these NUNit tests?

These three tests are identical, except that they use a different static function to create a StartInfo instance. I have this pattern coming up all trough my testcode, and would love
to be be able to simplify this using [TestCase], or any other way that reduces boilerplate code. To the best of my knowledge I'm not allowed to use a delegate as a [TestCase] argument, and I'm hoping people here have creative ideas on how to make the code below more terse.
[Test]
public void ResponseHeadersWorkinPlatform1()
{
DoResponseHeadersWorkTest(Platform1StartInfo.CreateOneRunning);
}
[Test]
public void ResponseHeadersWorkinPlatform2()
{
DoResponseHeadersWorkTest(Platform2StartInfo.CreateOneRunning);
}
[Test]
public void ResponseHeadersWorkinPlatform3()
{
DoResponseHeadersWorkTest(Platform3StartInfo.CreateOneRunning);
}
void DoResponseHeadersWorkTest(Func<ScriptResource,StartInfo> startInfoCreator)
{
ScriptResource sr = ScriptResource.Default;
var process = startInfoCreator(sr).Start();
//assert some things here
}
Firstly, I don't think the original is too bad. It's only messy if your assertions are different from test case to test case.
Anyway, you can use a test case, but it can't be done via a standard [TestCase] attribute due to using more complicated types. Instead, you need to use a public IEnumerable<> as the data provider and then tag your test method with a [TestCaseSource] attribute.
Try something like:
public IEnumerable<Func<ScriptResource, StartInfo>> TestCases
{
get
{
yield return Platform1StartInfo.CreateOneRunning;
yield return Platform2StartInfo.CreateOneRunning;
yield return Platform3StartInfo.CreateOneRunning;
}
}
[TestCaseSource("TestCases")]
public void MyDataDrivenTest(Func<ScriptResource, StartInfo> startInfoCreator)
{
ScriptResource sr = ScriptResource.Default;
var process = startInfoCreator(sr);
// do asserts
}
}
This is a more concise version of the standard pattern of yielding TestCaseData instances containing the parameters. If you yield instances of TestCaseData you can add more information and behaviours to each test (like expected exceptions, descriptions and so forth), but it is slightly more verbose.
Part of the reason I really like this stuff is that you can make one method for your 'act' and one method for your 'assert', then mix and match them independently. E.g. my friend was doing something yesterday where he used two Actions to say ("when method Blah is called, this method on the ViewModel should be triggered"). Very terse and effective!
It looks good. Are you looking to add a factory maybe ? Or you could add these methods to a Action List(in test setup) and call first action delegate, second action delegate and third action delegate.

asp.net MVC 2 - most elegant way of isolating guard code - guarding against null controller parameters

I have a very simple problem, but I'm looking for the 'best' solution to the following:
I have multiple controller actions something like this:
public ActionResult DoSomething(PackageViewModel packageByName, DoSomethingInputModel inputModel)
{
if (packageByName == null)
{
Response.StatusCode = 404;
Response.StatusDescription = "Package not found : " + RouteData.GetRequiredString("packageName");
return View("Error");
}
...
What is the best way to isolate this cross cutting concern?
I can make a function
I can use an AOP tool like PostSharp
ActionFilter
Other?
In fact ActionFilter is an AOP. Write your own ActionFilter implementation to chceck if parameter is not null. If you always need to check the same thing on the beggining of your controller execution then it's the best way. It's easy to write, resusable in whole application and very MVC 2.
Here's what I implemented (based on #ƁukaszW.pl answer)
Hopefully this will save someone some time.
public class GuardAgainstNullPackage : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
BookingController controller = ((BookingController)filterContext.Controller);
if (filterContext.ActionParameters["packageByName"] == null || !(filterContext.ActionParameters["packageByName"] is PackageViewModel))
{
controller.Response.StatusCode = 404;
controller.Response.StatusDescription = "Package not found : " + filterContext.RouteData.GetRequiredString("packageName");
filterContext.Result = new ViewResult() { ViewName = "Error" };
}
base.OnActionExecuting(filterContext);
}
}